HTTP API reference
This page is generated from the route table in
@bull-board/api. Do not edit it by hand: runyarn workspace @bull-board/api openapiinstead. The same content is browsable as an interactive reference, and machine-readable atopenapi.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
readOnlyModereject every write with 405 andERRORS.QUEUE_READ_ONLY. - A visibility guard makes a queue answer 404 as though it were not registered.
- A
handlerHooks.beforehook can reject any call, by default with 403 andERRORS.FORBIDDEN. - The four
/api/metrics/*routes are registered only when ahistoryProvideris 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.
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.
Responds 200 with GetQueuesResponse.
GET /api/queues/{queueName}/metrics
Read the BullMQ completed and failed counter metrics of one queue.
Responds 200 with GetQueueMetricsResponse.
GET /api/queues/{queueName}/default-job-options
Read the default job options configured on one queue.
Responds 200 with GetQueueDefaultJobOptionsResponse.
GET /api/queues/{queueName}/workers
List the workers currently consuming one queue.
Responds 200 with GetQueueWorkersResponse.
GET /api/queues/{queueName}/rate-limit
Read the configured rate limit of one queue.
Responds 200 with GetQueueRateLimitResponse.
PUT /api/queues/{queueName}/rate-limit
Set the rate limit of one queue.
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.
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.
Request body: AddJobBody
Responds 200 with AddJobResponse.
PUT /api/queues/{queueName}/retry/{queueStatus}
Retry every job of one queue in the given status.
Responds 200 with RetryAllResponse.
PUT /api/queues/{queueName}/promote
Promote every delayed job of one queue.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/clean/{queueStatus}
Remove every job of one queue in the given status.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/pause
Pause one queue.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/resume
Resume one queue.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/concurrency
Set the global concurrency limit of one queue.
Request body: SetGlobalConcurrencyBody
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/rate-limit/release
Release an active rate limit on one queue.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/empty
Remove every job from one queue.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/obliterate
Obliterate one queue, removing the queue itself along with all of its jobs.
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.
Responds 200 with GetJobLogsResponse.
GET /api/queues/{queueName}/{jobId}/flow
Read the flow tree one job belongs to.
Responds 200 with GetJobFlowResponse.
GET /api/queues/{queueName}/{jobId}
Read one job and its current status.
Responds 200 with GetJobResponse.
PUT /api/queues/{queueName}/{jobId}/retry
Retry one job.
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/{jobId}/clean
Remove one job.
Responds 204 with no body.
PUT /api/queues/{queueName}/{jobId}/promote
Promote one delayed job.
Responds 200 with EmptyResponse.
PATCH /api/queues/{queueName}/{jobId}/update-data
Replace the data of one job.
Request body: UpdateJobDataBody
Responds 200 with EmptyResponse.
PATCH /api/queues/{queueName}/{jobId}/delay
Reschedule one delayed job.
Request body: ChangeJobDelayBody
Responds 200 with EmptyResponse.
PATCH /api/queues/{queueName}/{jobId}/priority
Change the priority of one job.
Request body: ChangeJobPriorityBody
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/{jobId}/remove-unprocessed-children
Remove the unprocessed children of one job.
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.
Responds 200 with GetJobSchedulersResponse.
PUT /api/queues/{queueName}/job-schedulers/{schedulerId}/remove
Remove one job scheduler.
Responds 200 with EmptyResponse.
PATCH /api/queues/{queueName}/job-schedulers/{schedulerId}
Update the schedule of one job scheduler.
Request body: UpdateJobSchedulerBody
Responds 200 with EmptyResponse.
PUT /api/queues/{queueName}/job-schedulers/{schedulerId}/run
Run one job scheduler now, leaving its schedule untouched.
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
historyProvideris configured on the board.
Responds 200 with GetMetricsHistoryResponse.
GET /api/metrics/history/usage
Report how much storage the recorded history occupies.
Available only when: A
historyProvideris configured on the board. The provider implementsgetUsage.
Responds 200 with GetMetricsHistoryUsageResponse.
POST /api/metrics/history/purge
Delete recorded history.
Available only when: A
historyProvideris configured on the board. The provider implementspurgeand 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
historyProvideris configured on the board. The provider implementsgetLatency.
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
AppJobScheduler
AppQueue
ErrorResponseBody
ExternalJobUrl
FlowDependencies
FlowNode
JobCounts
object
JobFlow
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
MetricsHistoryPurgeResult
MetricsHistoryQueueUsage
MetricsHistoryTierUsage
MetricsHistoryUsage
MetricsLatencyPoint
Pagination
QueueType
bull` \| `bullmq
Status
latest` \| `active` \| `waiting` \| `waiting-children` \| `prioritized` \| `completed` \| `failed` \| `delayed` \| `paused
QueueDefaultJobOptions
QueueMetrics
QueueRateLimit
QueueWorker
RedisStats
TranslatableMessage
GetQueuesResponse
GetJobResponse
AddJobResponse
GetQueueMetricsResponse
GetQueueDefaultJobOptionsResponse
GetQueueJobDataSchemaResponse
object
GetQueueRateLimitResponse
GetQueueWorkersResponse
GetJobSchedulersResponse
RunJobSchedulerResponse
GetJobLogsResponse
string[]
GetJobFlowResponse
GetRedisStatsResponse
RedisStats \| object
GetMetricsHistoryResponse
GetMetricsHistoryUsageResponse
GetMetricsLatencyResponse
MetricsLatencyPoint[]
PurgeMetricsHistoryResponse
RetryAllResponse
RemoveUnprocessedChildrenResponse
EmptyResponse
GetQueuesQuery
GetJobSchedulersQuery
GetJobFlowQuery
GetMetricsHistoryQuery
GetMetricsLatencyQuery
AddJobBody
UpdateJobDataBody
ChangeJobDelayBody
ChangeJobPriorityBody
SetGlobalConcurrencyBody
SetRateLimitBody
object \| object