Every endpoint and schema of the QueueFlow REST API (OpenAPI 1.0.0), generated from the spec the server itself emits.
The server emits this document at /openapi.json and serves an interactive Swagger UI at /docs. A copy of the spec used to build this page is at /openapi.json; the canonical file lives in the queueflow-core repository and is attached to every release.
All /api/v1 routes require Authorization: Bearer <token>. Tenant routes take a tenant token (API key or JWT); the worker-protocol routes take the deployment's worker token. See Authentication and tenants. Durations are plain integer seconds; timestamps are RFC 3339 strings in UTC. Error responses share one shape:
json
{"error":"job not found","timestamp":"2026-10-06T12:00:00Z"}
Include the exact total count in the response (default false; the count is an extra full scan over the filtered set).
cursor
query
string
Opaque keyset cursor from a previous page's next_cursor. When set, offset is ignored and listing continues where that page ended.
created_after
query
string (date-time)
Only rows created at or after this instant (RFC 3339, inclusive). With created_before this forms the half-open range [after, before) — the natural shape for walking history period by period.
created_before
query
string (date-time)
Only rows created strictly before this instant (RFC 3339, exclusive).
Optional client-supplied key making this create idempotent per tenant: retrying with the same key returns the original job instead of creating a duplicate.
Stream a job's status transitions as Server-Sent Events until it reaches a terminal state. Lets clients await completion without polling the REST endpoint themselves.
Parameters
Name
In
Type
Description
idrequired
path
string
Job id
Responses
Status
Body
Meaning
200
string text/event-stream
SSE stream; each status event carries the full job JSON. Closes after the job reaches a terminal state.
Include the exact total count in the response (default false; the count is an extra full scan over the filtered set).
cursor
query
string
Opaque keyset cursor from a previous page's next_cursor. When set, offset is ignored and listing continues where that page ended.
created_after
query
string (date-time)
Only rows created at or after this instant (RFC 3339, inclusive). With created_before this forms the half-open range [after, before) — the natural shape for walking history period by period.
created_before
query
string (date-time)
Only rows created strictly before this instant (RFC 3339, exclusive).
Include the exact total count in the response (default false; the count is an extra full scan over the filtered set).
cursor
query
string
Opaque keyset cursor from a previous page's next_cursor. When set, offset is ignored and listing continues where that page ended.
created_after
query
string (date-time)
Only rows created at or after this instant (RFC 3339, inclusive). With created_before this forms the half-open range [after, before) — the natural shape for walking history period by period.
created_before
query
string (date-time)
Only rows created strictly before this instant (RFC 3339, exclusive).
Include the exact total count in the response (default false; the count is an extra full scan over the filtered set).
cursor
query
string
Opaque keyset cursor from a previous page's next_cursor. When set, offset is ignored and listing continues where that page ended.
created_after
query
string (date-time)
Only rows created at or after this instant (RFC 3339, inclusive). With created_before this forms the half-open range [after, before) — the natural shape for walking history period by period.
created_before
query
string (date-time)
Only rows created strictly before this instant (RFC 3339, exclusive).
Engine counters. Process-local and reset on restart: in a split api/worker deployment this reflects only the process serving the request; query the database for fleet-wide history.
A recurring enqueue schedule. Expressions are standard 5-field crontab (minute hour day-of-month month day-of-week), evaluated in UTC; a 6/7-field form with leading seconds is also accepted.
Field
Type
Description
created_atrequired
string (date-time)
cron_exprrequired
string
enabledrequired
boolean
idrequired
string
namerequired
string
Unique per tenant.
next_run_atrequired
string (date-time)
The next instant this schedule fires. Missed occurrences (server down) collapse into at most one catch-up firing.
A dead-lettered job: a terminal failure recorded for inspection and replay. The original job row remains (subject to retention); this entry captures why it died and, once replayed, which fresh job took its place.
Field
Type
Description
created_atrequired
string (date-time)
idrequired
integer (int64)
job_idrequired
string
reasonrequired
string
Why the job dead-lettered: max_attempts_exceeded, non_retryable, or handler_not_found.
error_message
string | null
queue_name
string | null
replay_job_id
string | null
The fresh job created by the replay.
replayed_at
string (date-time) | null
Set once this entry has been replayed; a dead letter replays at most once.
The job's current status. running means the lease was extended; anything else (cancelled, completed, ...) means it was not, and the worker should stop working on the job.
When the job becomes claimable. created_at for immediate jobs, the requested run_at for scheduled jobs, and the next backoff instant while retrying — the durable delay lives in the row itself.
How many times this job has been claimed (delivered to a worker). Greater than retry_count + 1 means a lease expired without a report — i.e. a worker crashed mid-run. (min 0)
error_message
string | null
idempotency_key
string | null
Client-supplied key that makes job creation idempotent per tenant: re-submitting the same key returns the original job instead of creating a duplicate.
metadata
object
next_retry_at
string (date-time) | null
When this job's next retry becomes claimable (mirrors scheduled_at while the job is retrying; kept for audit/inspection).
payload
object
result
object | null
started_at
string (date-time) | null
tenant_id
string | null
workflow_id
string | null
workflow_step_id
string | null
The owning workflow step's name (steps are addressed by name).
Per-job execution configuration. All durations are in seconds. Deserialization is partial-friendly: any omitted field takes its [JobConfig::default] value (via per-field serde defaults), so workflow-step and cron config overrides can name just the fields they change, and out-of-band rows with sparse config JSONB still load. Per-field functions rather than a struct-level #[serde(default)]: the struct-level form makes utoipa attach a default beside the BackoffStrategy$ref, which forces a synthetic wrapper type into every generated SDK.
Field
Type
Description
jitter_factor
number (double) | null
Optional jitter in 0.0..=1.0. 0.1 => +/-10% randomization of each retry delay, which spreads out thundering-herd retries.
max_retries
integer (int32)
(min 0)
priority
integer (int32)
Higher is claimed first within a queue; ties break on scheduled_at, then created_at.
Opaque, unguessable proof of lease ownership, regenerated on every claim. Pass it back on heartbeat/complete/fail; a stale token (the lease expired and the job was reclaimed) is rejected.
Opaque keyset cursor for the next page (present when has_more). Pass it back as cursor to continue where this page ended; cheaper than deep OFFSET paging.
total
integer (int64) | null
Exact total match count; only present when include_total=true.
Opaque keyset cursor for the next page (present when has_more). Pass it back as cursor to continue where this page ended; cheaper than deep OFFSET paging.
total
integer (int64) | null
Exact total match count; only present when include_total=true.
Opaque keyset cursor for the next page (present when has_more). Pass it back as cursor to continue where this page ended; cheaper than deep OFFSET paging.
total
integer (int64) | null
Exact total match count. Only present when the request set include_total=true; computing it costs a full count over the filtered set, so it is opt-in.
Opaque keyset cursor for the next page (present when has_more). Pass it back as cursor to continue where this page ended; cheaper than deep OFFSET paging.
total
integer (int64) | null
Exact total match count; only present when include_total=true.