Management API
@monque/management provides HTTP endpoints for job listings, queue counts, scheduler
health, and job actions. Use the same Monque instance that processes your application’s
jobs so worker activity and health describe that scheduler.
For Express, start with Express API setup. To add a browser interface, see Dashboard setup.
Use without Express
Section titled “Use without Express”Create a Management handler from an initialized instance:
request is a standard Request supplied by your HTTP server. Return the response through
that server and pass unmatched requests to its other routes. Authenticate requests before
calling the handler and derive managementContext from the authenticated session.
The Fetch handler returned by createManagementSurface and the router returned by
createManagementExpressRouter enforce the origin checks and body limits below. If you
mount createManagementRouter with a custom oRPC HTTP handler, configure both protections
on that handler.
Browser mutation protection
Section titled “Browser mutation protection”The HTTP handler rejects mutations with an untrusted Origin using 403, before reading
the body or invoking authorization and job operations. Same-origin browser requests work
by default. Other origins, including sibling subdomains, must be explicitly trusted:
Each entry must be an exact HTTP or HTTPS origin, including a port when required, without
a trailing slash, path, credentials, query, or fragment. Wildcards are not accepted.
Malformed and null request origins are always rejected. The default same-origin check
uses the supplied Request URL, so adapters must preserve its correct scheme and host.
Server clients without Origin remain supported. When Origin is absent, browser
Sec-Fetch-Site values of same-site, cross-site, or an invalid value are rejected;
same-origin and none are accepted. Read endpoints are unaffected. Authentication and
operation authorization are still required, and CORS remains host-owned. For a trusted
cross-origin Dashboard, allow only that origin in credentialed CORS and configure cookies
for the intended browser access.
Request body limits
Section titled “Request body limits”Management accepts request bodies up to 64 KiB by default. Larger bodies return HTTP 413
before operation authorization, job lookups, or mutations. The limit counts bytes as the
body arrives, including requests without a Content-Length header.
Set maxBodySize in bytes when creating a Management Surface or Express router:
Use a nonnegative safe integer. Responses, including job payloads, are not limited by
this setting. Configure your proxy and host body parser limits too: if middleware such
as express.json() parses a body before Management, its original allocation has already
happened, and Management checks the adapter’s serialized body instead.
Endpoints
Section titled “Endpoints”Paths are relative to the Management router’s mount URL:
| Method | Path | Operation |
|---|---|---|
GET | /api/v1/health | Scheduler health |
GET | /api/v1/capabilities | Read-only mode and available actions |
GET | /api/v1/processing | Local pause state and scheduler identity; optional name |
POST | /api/v1/processing/actions/pause | Pause all local workers or one job name |
POST | /api/v1/processing/actions/resume | Resume all local workers or one job name |
GET | /api/v1/queue-views | Job counts grouped by name and local worker activity |
GET | /api/v1/jobs | Cursor-paginated jobs |
GET | /api/v1/jobs/stats | Job counts, optionally filtered by name |
GET | /api/v1/jobs/{id} | Job detail and payload |
POST | /api/v1/jobs/{id}/actions/cancel | Cancel a pending job |
POST | /api/v1/jobs/{id}/actions/retry | Retry a failed or cancelled job |
POST | /api/v1/jobs/{id}/actions/reschedule | Change a pending job’s run time |
POST | /api/v1/jobs/{id}/actions/priority | Change a pending Job’s priority |
DELETE | /api/v1/jobs/{id} | Delete a job |
POST | /api/v1/jobs/actions/cancel | Cancel jobs matching a selector |
POST | /api/v1/jobs/actions/retry | Retry jobs matching a selector |
POST | /api/v1/jobs/actions/delete | Delete jobs matching a selector |
POST | /api/v1/jobs/actions/selected | Act on specific job IDs |
Job IDs are MongoDB ObjectId strings. Dates in requests and responses use ISO 8601 UTC
strings, such as 2026-09-19T12:00:00.000Z. Job responses use payload for the job’s data
and failureReason for its latest failure. Absent lock and heartbeat timestamps are null;
absent heartbeatInterval, repeatInterval, timezone, and uniqueKey fields are omitted.
Jobs using renewable leases also include leaseExpiresAt, an ISO UTC deadline measured
by MongoDB. Heartbeats extend it while the claim remains valid. Jobs using absolute
lockTimeout have no lease deadline field. Details, full and summary listings, and
job action responses use the same representation.
Queue views include the local worker’s effective paused state, hasSchema flag, and
retry settings (maxRetries, baseRetryInterval, maxBackoffDelay). Delays are in
milliseconds. These settings describe new executions on the attached scheduler;
already-running jobs retain the policies captured when they started. A global pause
also makes each local worker appear paused. Other scheduler instances may still run jobs.
Custom scheduler facades can omit these fields when the information is unavailable.
Validator functions and schemas are never serialized.
Recurring jobs expose their configured IANA timezone in detail, full and summary listings,
and job action responses. When omitted, the schedule uses the worker server’s local timezone.
This metadata does not change UTC timestamp serialization. Rescheduling changes only the next
run time; it preserves the recurring cron expression and timezone.
Jobs stopped by a worker’s NonRetryableError use the existing failed status and expose
failureReason and the actual failCount, which may be only one. Existing single and bulk
retry endpoints remain available. No Management or Express adapter upgrade is required
for this behavior; the worker must use core 1.14.0 or later.
Pause and resume processing
Section titled “Pause and resume processing”Read /api/v1/processing first, then send its instanceId to either control endpoint:
Omit name to control the whole attached scheduler. These controls are process-local:
other instances continue processing. Running handlers finish and their leases keep renewing.
Resuming the instance preserves individual worker pauses; resuming a worker cannot override
an instance-wide pause. Responses include the effective paused state and globallyPaused.
Pauses do not survive process restarts.
GET /api/v1/capabilities?name=send-email checks processing permissions for that worker
using the attached scheduler’s identity. Without name, it checks instance-wide controls.
The other job-action capability checks remain unscoped.
The pause and resume authorization actions receive name and instanceId. Read-only
mode denies both. Capabilities report them unavailable when the scheduler facade omits
the corresponding methods or getProcessingState(). State reads require read access.
A different scheduler identity returns 409 without changing processing. Behind a load
balancer, use instance-specific or sticky routing. Refresh state after a conflict and
confirm the intended instance before retrying. Give each scheduler a unique
schedulerInstanceId if overriding the generated identifier.
Job listings
Section titled “Job listings”GET /api/v1/jobs accepts:
| Parameter | Meaning |
|---|---|
name | Exact job name; substring and payload search are not supported. |
status | pending, processing, completed, failed, or cancelled. Repeat the parameter for multiple statuses. |
limit | Positive page size; defaults to 50 and values above 100 are capped at 100. |
cursor | Opaque cursor returned by the previous response. |
sortBy | identifier, createdAt (default), updatedAt, or nextRunAt. |
sortDirection | asc or desc; defaults to desc. |
createdAtFrom, createdAtTo | Inclusive creation-time range. |
updatedAtFrom, updatedAtTo | Inclusive update-time range. |
nextRunAtFrom, nextRunAtTo | Inclusive scheduled-time range. |
view | full (default) or summary. |
Responses include jobs, cursor, hasNextPage, and hasPreviousPage. Keep the same
filters and sort when following a cursor. Start a new page sequence when changing them.
view=summary returns metadata with payload: null and skips payload serialization. With
a scheduler that supports summary queries, it also avoids loading payloads from MongoDB.
Use the job detail endpoint when you need the payload. Full listings retain payload
serialization and redaction.
Change one Job’s priority
Section titled “Change one Job’s priority”Send POST /api/v1/jobs/{id}/actions/priority with a signed safe integer:
Success returns the updated Job. The operation applies only to pending Jobs and leaves their
scheduled time unchanged. For a recurring Job, the new priority also applies to future runs.
Invalid input returns 400, a missing Job returns 404, and a Job claimed before the update
returns 409. Processing and terminal Jobs also return 409.
The setJobPriority authorization action receives the target job and request context.
The matching capability, actions.setJobPriority, reflects method support, read-only mode,
and authorization for the request. A scheduler without setJobPriority, a denied action,
or a read-only surface returns 403. Capability checks have no target Job; the mutation
checks authorization again with the current Job.
The Dashboard shows Change priority with its other Job actions. Enter a signed safe integer and confirm before applying it. Only pending Jobs with an available capability can be changed. After success, the table and detail refresh; unrelated valid selections remain. A stale state or authorization change shows the server error instead of a success message.
Selected job actions
Section titled “Selected job actions”Post a JSON body to /api/v1/jobs/actions/selected:
Supported actions are cancel, retry, delete, reschedule, and priority. Rescheduling
requires nextRunAt; a priority change requires priority. Requests accept 1 to 100 IDs
before deduplication. Duplicate IDs are processed and counted once, including IDs that
differ only in letter case. Only the supplied IDs are targets; filters and cursor pages
never widen the selection.
The response reports successful changes and individual failures:
A response can contain both successes and failures. Successful changes are not rolled back
when another job fails. Check errors even when the request returns HTTP 200.
Change selected priorities
Section titled “Change selected priorities”Send POST /api/v1/jobs/actions/selected with one priority for the selected Jobs:
The priority must be a signed JavaScript safe integer. Invalid input returns 400 before
any Job changes. Each target must still be pending when the API applies the change;
future Jobs are eligible too. The operation keeps each Job’s scheduled time and uses the
same setJobPriority permission and capability as a single-Job change. Read-only mode
and schedulers without that method reject the action with 403.
Authorization first checks setJobPriority with the selected ids, then checks the same
action with each current job and request context. A missing Job returns a per-Job 404,
a denied Job returns 403, and a processing or terminal Job returns 409. A Job claimed
before its update also returns 409. Other selected Jobs can succeed; failed and unselected
Jobs keep their values. There is no selector-wide priority action.
In the Dashboard, select pending Jobs and choose Change priority. The bulk control is available only when every selected Job is pending and the action is enabled. Enter one priority, then review the selected count and value before confirming. The server rechecks state and permissions, so changes after selection can produce partial results.
After the response, the Dashboard refreshes priorities, clears successful IDs from the selection, and reports success and failure counts with the first error. Failed IDs and unrelated selections remain selected while their rows are still in the current view. Polling preserves those selections and removes IDs whose rows disappear from the view.
Selector-based bulk actions
Section titled “Selector-based bulk actions”The /actions/cancel, /actions/retry, and /actions/delete endpoints accept a selector:
Selectors support name, status, olderThan, and newerThan. Date bounds refer to job
creation time. These operations affect matching jobs across all pages. An empty selector
matches all jobs eligible for the action. Use selected job actions when you want to target
only explicit IDs or require authorization for each job.
Authorization
Section titled “Authorization”Authentication establishes who is making a request. Your HTTP server must handle it before
Management. authorize then decides which operations that user may perform:
Available action names are read, cancel, cancelBulk, retry, retryBulk, reschedule,
setJobPriority, delete, and deleteBulk. The callback receives:
| Input | Available when |
|---|---|
context | Every authorization check |
job | A single job is targeted |
selector | A selector-based bulk operation is requested |
ids | The initial check for a selected-job request |
Capabilities checks do not include a job, selector, or IDs. Handle those inputs as optional.
Selected cancel, retry, and delete requests first check the corresponding bulk permission,
then the individual permission for each job. Selected rescheduling checks reschedule at
both stages; selected priority changes check setJobPriority at both stages. Selector-based
bulk actions check the selector once, without per-job checks.
Set readOnly: true to reject all mutations with HTTP 403. It does not bypass read
authorization. Without authorize, supported operations are allowed unless read-only mode
blocks them. Unsupported actions also return 403.
Read authorization allows or denies the read operation as a whole; it does not filter jobs
by tenant or hide individual Queue Views. Health reports the scheduler’s running state and
is available without a read authorization check, so protect the entire HTTP mount with
authentication middleware when needed.
parallelCapabilityChecks: true runs capability authorization checks concurrently. Enable
it only if your callback can run independent checks without relying on their order.
The default is sequential.
Payload redaction
Section titled “Payload redaction”Choose which payload fields API clients can see:
Install Zod with bun add zod if your application does not already use it.
This returns only the email subject and hides all other payloads. A serializer registered
for a job name takes precedence over the default serializer. Both receive job and request
context, so you can decide which fields a user may see. Redaction affects
API responses and the dashboard, not the payload stored in MongoDB. Without a serializer,
Management returns the job data.
Clients and API reference
Section titled “Clients and API reference”Use the OpenAPI document served by the Express adapter
with an OpenAPI client generator. To generate a document yourself, call
generateManagementOpenApiDocument().
TypeScript clients can import managementContract and DTO schemas from
@monque/management/contract. See the Management API reference
for exported types and functions.
To enqueue jobs, register workers, or start and stop the scheduler, use the Core API operations.