For AI agents: the complete documentation index is available at /bull-board/llms.txt, the full documentation bundle is available at /bull-board/llms-full.txt, and this page is available as Markdown at /bull-board/reference/http-api.md.

HTTP API reference

This page is generated from the route table in @bull-board/api. Do not edit it by hand: run yarn workspace @bull-board/api openapi instead. The same content is browsable as an interactive reference, and machine-readable at openapi.json.

The dashboard's own UI is a client of this API and nothing else, so anything the UI can do is available here. Every route is served relative to the base path you passed to setBasePath(). A board mounted at /admin/queues serves GET /admin/queues/api/queues.

Authentication

There is none. bull-board does not authenticate requests and never has: the board inherits whatever protects the route it is mounted on, which is your application's own middleware. See basic auth for the standalone case, and access control hooks for per-route rules.

This matters when pointing a script or an agent at a running board. You send whatever credential your own middleware expects, as an ordinary header, and bull-board neither issues nor validates it.

What can reject a call

A route existing in this document does not mean a given board will answer it.

  • Queues registered with readOnlyMode reject every write with 405 and ERRORS.QUEUE_READ_ONLY.
  • A visibility guard makes a queue answer 404 as though it were not registered.
  • A handlerHooks.before hook can reject any call, by default with 403 and ERRORS.FORBIDDEN.
  • The four /api/metrics/* routes are registered only when a historyProvider is configured, and individually only when the provider implements the matching capability. Without one they are not mounted at all and answer 404. See historical metrics.

Request validation

Every query string and request body documented here is checked against its schema before the route runs, and a request that does not match is refused with 400 before anything is read or written. The check runs after handlerHooks.before, so a hook that hides a route still answers first and a malformed request cannot be used to discover that a hidden route exists.

Query values arrive as strings and are coerced by the schema, which is why parameters such as page document a string alongside a number: the wire carries page=2 and the handler receives 2. An empty value reads as an omitted one, so ?page= is the same request as no page at all.

Error bodies

Every failure returns ErrorResponseBody. Its error field is a translation key rather than a sentence, because the API never puts user-facing English in a response and the client owns the wording. code is the stable identifier to branch on when you handle a specific failure rather than display it.

{
  "error": { "key": "ERRORS.QUEUE_NOT_FOUND" },
  "message": { "key": "ERRORS.JOB_IS_ACTIVE_DETAILS", "options": { "jobId": "42" } },
  "code": "JOB_BELONGS_TO_JOB_SCHEDULER"
}

Response shapes

Every response documented here is derived from the same schema the handler is type-checked against, so a handler that stops returning what it advertises does not compile. A board can also check its responses at runtime with options.validateResponses, which is meant for developing a custom adapter or hook rather than for production.

Versioning

The info.version in the spec describes the shape of this HTTP API and is deliberately independent of the @bull-board/api package version, so a routine release does not churn the generated artifacts.

Queues

Board-level and per-queue operations. GET /api/queues is the one the dashboard polls: it returns counts for every queue the request may see, and the jobs of only the queue named in activeQueue, paged by page and jobsPerPage. Everything else here acts on a single queue named in the path, and is refused with 405 when that queue was registered read-only.

GET /api/queues

List every visible queue with its job counts, and the jobs of the active queue.

ParameterInRequiredType
activeQueuequerynostring
statusquerynoStatus
pagequerynostring
jobsPerPagequerynostring

Responds 200 with GetQueuesResponse.

GET /api/queues/{queueName}/metrics

Read the BullMQ completed and failed counter metrics of one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with GetQueueMetricsResponse.

GET /api/queues/{queueName}/default-job-options

Read the default job options configured on one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with GetQueueDefaultJobOptionsResponse.

GET /api/queues/{queueName}/workers

List the workers currently consuming one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with GetQueueWorkersResponse.

GET /api/queues/{queueName}/rate-limit

Read the configured rate limit of one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with GetQueueRateLimitResponse.

PUT /api/queues/{queueName}/rate-limit

Set the rate limit of one queue.

ParameterInRequiredType
queueNamepathyesstring

Request body: SetRateLimitBody

Responds 200 with EmptyResponse.

GET /api/queues/{queueName}/job-data-schema

Read the JSON Schema describing the job data of one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with GetQueueJobDataSchemaResponse.

PUT /api/queues/pause

Pause every writable queue on the board.

Responds 200 with EmptyResponse.

PUT /api/queues/resume

Resume every writable queue on the board.

Responds 200 with EmptyResponse.

POST /api/queues/{queueName}/add

Add a job to one queue.

ParameterInRequiredType
queueNamepathyesstring

Request body: AddJobBody

Responds 200 with AddJobResponse.

PUT /api/queues/{queueName}/retry/{queueStatus}

Retry every job of one queue in the given status.

ParameterInRequiredType
queueNamepathyesstring
queueStatuspathyesstring

Responds 200 with RetryAllResponse.

PUT /api/queues/{queueName}/promote

Promote every delayed job of one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/clean/{queueStatus}

Remove every job of one queue in the given status.

ParameterInRequiredType
queueNamepathyesstring
queueStatuspathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/pause

Pause one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/resume

Resume one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/concurrency

Set the global concurrency limit of one queue.

ParameterInRequiredType
queueNamepathyesstring

Request body: SetGlobalConcurrencyBody

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/rate-limit/release

Release an active rate limit on one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/empty

Remove every job from one queue.

ParameterInRequiredType
queueNamepathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/obliterate

Obliterate one queue, removing the queue itself along with all of its jobs.

ParameterInRequiredType
queueNamepathyesstring

Request body: ObliterateQueueBody

Responds 200 with EmptyResponse.

Jobs

Reads and mutations for one job, addressed by its queue and id. Removing a job that is the pending run of a job scheduler is refused with 400 and the JOB_BELONGS_TO_JOB_SCHEDULER code, because deleting it alone would leave the schedule registered but unable to fire again.

GET /api/queues/{queueName}/{jobId}/logs

Read the logs of one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 200 with GetJobLogsResponse.

GET /api/queues/{queueName}/{jobId}/flow

Read the flow tree one job belongs to.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring
rootquerynoany
depthquerynoobject
maxChildrenquerynoobject

Responds 200 with GetJobFlowResponse.

GET /api/queues/{queueName}/{jobId}

Read one job and its current status.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 200 with GetJobResponse.

PUT /api/queues/{queueName}/{jobId}/retry

Retry one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/{jobId}/clean

Remove one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 204 with no body.

PUT /api/queues/{queueName}/{jobId}/promote

Promote one delayed job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 200 with EmptyResponse.

PATCH /api/queues/{queueName}/{jobId}/update-data

Replace the data of one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Request body: UpdateJobDataBody

Responds 200 with EmptyResponse.

PATCH /api/queues/{queueName}/{jobId}/delay

Reschedule one delayed job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Request body: ChangeJobDelayBody

Responds 200 with EmptyResponse.

PATCH /api/queues/{queueName}/{jobId}/priority

Change the priority of one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Request body: ChangeJobPriorityBody

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/{jobId}/remove-unprocessed-children

Remove the unprocessed children of one job.

ParameterInRequiredType
queueNamepathyesstring
jobIdpathyesstring

Responds 200 with RemoveUnprocessedChildrenResponse.

Job schedulers

Repeatable job definitions, meaning the schedule itself rather than the runs it produces. Listing spans every visible queue unless you name one. Editing a schedule replaces it, so a body that sets neither a cron pattern nor an interval is rejected.

GET /api/job-schedulers

List job schedulers across every visible queue, or one named queue.

ParameterInRequiredType
queueNamequerynostring

Responds 200 with GetJobSchedulersResponse.

PUT /api/queues/{queueName}/job-schedulers/{schedulerId}/remove

Remove one job scheduler.

ParameterInRequiredType
queueNamepathyesstring
schedulerIdpathyesstring

Responds 200 with EmptyResponse.

PATCH /api/queues/{queueName}/job-schedulers/{schedulerId}

Update the schedule of one job scheduler.

ParameterInRequiredType
queueNamepathyesstring
schedulerIdpathyesstring

Request body: UpdateJobSchedulerBody

Responds 200 with EmptyResponse.

PUT /api/queues/{queueName}/job-schedulers/{schedulerId}/run

Run one job scheduler now, leaving its schedule untouched.

ParameterInRequiredType
queueNamepathyesstring
schedulerIdpathyesstring

Responds 200 with RunJobSchedulerResponse.

Metrics history

Long-retention counter and latency history. These routes exist only on a board configured with a historyProvider, and each one individually only when the provider implements the matching capability, so on a board without one they are not mounted and answer 404.

GET /api/metrics/history

Read recorded job counter history over a time range.

Available only when: A historyProvider is configured on the board.

ParameterInRequiredType
fromqueryyesstring
toqueryyesstring
granularityquerynoMetricsHistoryGranularity
queuequerynostring
metricquerynoMetricsHistoryMetric

Responds 200 with GetMetricsHistoryResponse.

GET /api/metrics/history/usage

Report how much storage the recorded history occupies.

Available only when: A historyProvider is configured on the board. The provider implements getUsage.

Responds 200 with GetMetricsHistoryUsageResponse.

POST /api/metrics/history/purge

Delete recorded history.

Available only when: A historyProvider is configured on the board. The provider implements purge and the board is not read-only.

Request body: PurgeMetricsHistoryBody

Responds 200 with PurgeMetricsHistoryResponse.

GET /api/metrics/latency

Read recorded runtime or wait-time latency percentiles over a time range.

Available only when: A historyProvider is configured on the board. The provider implements getLatency.

ParameterInRequiredType
metricqueryyesMetricsLatencyMetric
fromquerynostring
toquerynostring
granularityquerynohour | day | range
queuequerynostring
percentilesquerynostring

Responds 200 with GetMetricsLatencyResponse.

Datastore

Statistics for the datastore behind the board's first registered queue. Answers 404 when that queue is backed by something other than Redis that cannot report them, and 403 when the board sets hideRedisDetails.

GET /api/redis/stats

Read the datastore statistics of the board's first queue.

Responds 200 with GetRedisStatsResponse.

Schemas

AppJob

FieldTypeRequired
idstring | number | nullno
namestringyes
timestampnumberyes
processedOnnumber | nullno
processedBystring | nullno
finishedOnnumber | nullno
progressstring | boolean | number | objectyes
attemptsnumberyes
failedReasonstringno
stacktracestring[]yes
delaynumberno
optsanyyes
dataanyyes
returnValueanyyes
isFailedbooleanyes
externalUrlExternalJobUrlno
groupIdstring | numberno
prioritynumberno
attemptsStartednumberno
stalledCounternumberno
deduplicationIdstringno
deferredFailurestringno

AppJobScheduler

FieldTypeRequired
idstringyes
queueNamestringyes
namestringyes
patternstringno
everynumberno
tzstringno
limitnumberno
startDatenumberno
endDatenumberno
nextnumberno
nextRunJobIdstringno
lastRunnumberno
lastRunJobIdstringno
iterationCountnumberno
templateobjectno

AppQueue

FieldTypeRequired
delimiterstringyes
namestringyes
displayNamestringno
descriptionstringno
countsJobCountsyes
jobsAppJob[]yes
statusesStatus[]yes
paginationPaginationyes
readOnlyModebooleanyes
allowRetriesbooleanyes
allowCompletedRetriesbooleanyes
isPausedbooleanyes
typeQueueTypeyes
globalConcurrencynumber | nullyes
activeRateLimitTtlnumberyes
supportsGlobalRateLimitbooleanyes
jobSchedulerCountnumberyes
hasWorkersboolean | nullyes

ErrorResponseBody

FieldTypeRequired
errorobjectyes
messagestring | TranslatableMessageno
codestringno
detailsstringno

ExternalJobUrl

FieldTypeRequired
displayTextstringno
hrefstringyes

FlowDependencies

FieldTypeRequired
processednumberyes
unprocessednumberyes
ignorednumberyes
failednumberyes

FlowNode

FieldTypeRequired
idstringyes
namestringyes
statestringyes
progressstring | boolean | number | objectyes
queueNamestringyes
childrenFlowNode[]yes
truncatedbooleanno
dependenciesFlowDependenciesno
ignoredChildFailureReasonsobjectno

JobCounts

object

JobFlow

FieldTypeRequired
nodeIdstringyes
isFlowNodebooleanyes
flowRootFlowNode | nullyes

JobState

latest` \| `active` \| `waiting` \| `waiting-children` \| `prioritized` \| `completed` \| `failed` \| `delayed` \| `paused` \| `stuck` \| `unknown

JobStatus

active` \| `waiting` \| `waiting-children` \| `prioritized` \| `completed` \| `failed` \| `delayed` \| `paused

MetricsHistoryGranularity

hour` \| `day

MetricsHistoryMetric

completed` \| `failed` \| `queueage

MetricsLatencyGranularity

hour` \| `day` \| `range

MetricsLatencyMetric

runtime` \| `waittime

MetricsHistoryPoint

FieldTypeRequired
tsnumberyes
valuenumberyes

MetricsHistoryPurgeResult

FieldTypeRequired
keysDeletednumberyes
fieldsDeletednumberyes

MetricsHistoryQueueUsage

FieldTypeRequired
queuestringyes
keysnumberyes
bytesnumberyes
minutesnumberyes
daysstring[]yes
tiersobjectyes

MetricsHistoryTierUsage

FieldTypeRequired
keysnumberyes
bytesnumberyes

MetricsHistoryUsage

FieldTypeRequired
keysnumberyes
bytesnumberyes
minutesnumberyes
oldestDaystring | nullyes
newestDaystring | nullyes
tiersobjectyes
queuesMetricsHistoryQueueUsage[]yes

MetricsLatencyPoint

FieldTypeRequired
tsnumberyes
countnumberyes
valuesobjectyes

Pagination

FieldTypeRequired
pageCountnumberyes
rangeobjectyes

QueueType

bull` \| `bullmq

Status

latest` \| `active` \| `waiting` \| `waiting-children` \| `prioritized` \| `completed` \| `failed` \| `delayed` \| `paused

QueueDefaultJobOptions

FieldTypeRequired
attemptsnumberno
delaynumberno
prioritynumberno
lifobooleanno
backoffnumber | objectno
removeOnCompleteboolean | number | objectno
removeOnFailboolean | number | objectno

QueueMetrics

FieldTypeRequired
metaobjectyes
datanumber[]yes
countnumberyes

QueueRateLimit

FieldTypeRequired
maxnumberyes
durationnumberyes

QueueWorker

FieldTypeRequired
idstringyes
namestring | nullyes
addrstringyes
agenumberyes

RedisStats

FieldTypeRequired
backendredis | postgresno
versionstringyes
modestandalone | sentinel | clusterno
portnumberyes
osstringno
uptimenumberyes
memoryobjectno
clientsobjectyes

TranslatableMessage

FieldTypeRequired
keyERRORS.FORBIDDEN | ERRORS.INTERNAL_SERVER_ERROR | ERRORS.INVALID_BEFORE_DATE | ERRORS.INVALID_CONCURRENCY | ERRORS.INVALID_DATE_RANGE | ERRORS.INVALID_GRANULARITY | ERRORS.INVALID_METRIC | ERRORS.INVALID_PRIORITY | ERRORS.INVALID_QUEUE | ERRORS.INVALID_QUERY_PARAM | ERRORS.INVALID_RATE_LIMIT | ERRORS.INVALID_REQUEST_BODY | ERRORS.INVALID_RUN_AT | ERRORS.INVALID_SCHEDULER_END_DATE | ERRORS.INVALID_SCHEDULER_INTERVAL | ERRORS.INVALID_SCHEDULER_LIMIT | ERRORS.INVALID_SCHEDULER_PATTERN | ERRORS.INVALID_SCHEDULER_SCHEDULE | ERRORS.JOB_BELONGS_TO_JOB_SCHEDULER | ERRORS.JOB_BELONGS_TO_JOB_SCHEDULER_DETAILS | ERRORS.JOB_EDIT_NOT_SUPPORTED | ERRORS.JOB_HAS_NO_UNPROCESSED_CHILDREN | ERRORS.JOB_IS_ACTIVE | ERRORS.JOB_IS_ACTIVE_DETAILS | ERRORS.JOB_NOT_DELAYED | ERRORS.JOB_NOT_FOUND | ERRORS.JOB_NOT_RETRIABLE | ERRORS.JOB_SCHEDULER_EDIT_NOT_SUPPORTED | ERRORS.JOB_SCHEDULER_NOT_FOUND | ERRORS.JOB_SCHEDULER_RUN_NOT_SUPPORTED | ERRORS.JOB_UNPROCESSED_CHILDREN_NOT_SUPPORTED | ERRORS.QUEUE_HAS_ACTIVE_JOBS | ERRORS.QUEUE_HAS_ACTIVE_JOBS_DETAILS | ERRORS.QUEUE_NOT_FOUND | ERRORS.QUEUE_NOT_PAUSED | ERRORS.QUEUE_READ_ONLY | ERRORS.RATE_LIMIT_NOT_SUPPORTED | ERRORS.REDIS_STATS_UNAVAILABLE | ERRORS.REDIS_UNAVAILABLE | ERRORS.STATUS_NOT_RETRIABLE | ERRORS.WORKERS_DISABLEDyes
optionsobjectno

GetQueuesResponse

FieldTypeRequired
queuesAppQueue[]yes

GetJobResponse

FieldTypeRequired
jobAppJobyes
statusJobStateyes

AddJobResponse

FieldTypeRequired
jobAppJobyes
statusJobStateyes

GetQueueMetricsResponse

FieldTypeRequired
completedQueueMetrics | nullyes
failedQueueMetrics | nullyes

GetQueueDefaultJobOptionsResponse

FieldTypeRequired
attemptsnumberno
delaynumberno
prioritynumberno
lifobooleanno
backoffnumber | objectno
removeOnCompleteboolean | number | objectno
removeOnFailboolean | number | objectno

GetQueueJobDataSchemaResponse

object

GetQueueRateLimitResponse

FieldTypeRequired
supportedbooleanyes
rateLimitQueueRateLimit | nullyes

GetQueueWorkersResponse

FieldTypeRequired
workersQueueWorker[] | nullyes

GetJobSchedulersResponse

FieldTypeRequired
schedulersAppJobScheduler[]yes

RunJobSchedulerResponse

FieldTypeRequired
jobAppJobyes

GetJobLogsResponse

string[]

GetJobFlowResponse

FieldTypeRequired
nodeIdstringyes
isFlowNodebooleanyes
flowRootFlowNode | nullyes

GetRedisStatsResponse

RedisStats \| object

GetMetricsHistoryResponse

FieldTypeRequired
completedMetricsHistoryPoint[]no
failedMetricsHistoryPoint[]no
queueageMetricsHistoryPoint[]no

GetMetricsHistoryUsageResponse

FieldTypeRequired
keysnumberyes
bytesnumberyes
minutesnumberyes
oldestDaystring | nullyes
newestDaystring | nullyes
tiersobjectyes
queuesMetricsHistoryQueueUsage[]yes

GetMetricsLatencyResponse

MetricsLatencyPoint[]

PurgeMetricsHistoryResponse

FieldTypeRequired
keysDeletednumberyes
fieldsDeletednumberyes

RetryAllResponse

FieldTypeRequired
retriednumberyes
skippednumberyes

RemoveUnprocessedChildrenResponse

FieldTypeRequired
removednumberyes

EmptyResponse

FieldTypeRequired

GetQueuesQuery

FieldTypeRequired
activeQueuestringno
statusStatusno
pagestringno
jobsPerPagestringno

GetJobSchedulersQuery

FieldTypeRequired
queueNamestringno

GetJobFlowQuery

FieldTypeRequired
rootanyno
depthobjectno
maxChildrenobjectno

GetMetricsHistoryQuery

FieldTypeRequired
fromstringyes
tostringyes
granularityMetricsHistoryGranularityno
queuestringno
metricMetricsHistoryMetricno

GetMetricsLatencyQuery

FieldTypeRequired
metricMetricsLatencyMetricyes
fromstringno
tostringno
granularityhour | day | rangeno
queuestringno
percentilesstringno

AddJobBody

FieldTypeRequired
namestringno
dataanyno
optionsobjectno

UpdateJobDataBody

FieldTypeRequired
jobDataanyyes

ChangeJobDelayBody

FieldTypeRequired
runAtnumberyes

ChangeJobPriorityBody

FieldTypeRequired
priorityintegeryes

SetGlobalConcurrencyBody

FieldTypeRequired
concurrencyintegeryes

SetRateLimitBody

object \| object

ObliterateQueueBody

FieldTypeRequired
forcebooleanno

UpdateJobSchedulerBody

FieldTypeRequired
patternstringno
everystring | number | nullno
tzstringno
limitinteger | nullno
endDatestring | number | nullno

PurgeMetricsHistoryBody

FieldTypeRequired
queuestringno
beforestringno