Skip to content

API reference

The SimpleQ REST API: publish jobs, manage queues, and operate the dead-letter queue. You publish a job over HTTP; SimpleQ queues it, applies retries and rate limits, and delivers it to your webhook. Every endpoint, request body, and status code is listed below.

  • Base URL: https://api.simpleq.io
  • Auth: send Authorization: Bearer sq_live_... on every request. Create and revoke keys from the dashboard. All durations are in seconds.

Try it in your browser → Interactive API explorer — send live requests against the API.

Machine-readable spec: openapi.json — import it to generate a client.

Client libraries: TypeScript — @simpleq/sdk (npm install @simpleq/sdk) · GitHub · npm.

Changing a setting on an existing queue? See Editing a queue for when each change takes effect.

Jobs

Publish jobs, check status, and retry failures.

POST /v1/queues/{queueName}/jobs

Publish a job Queues a job for delivery to the queue’s webhook. If idempotencyKey matches a previously published job, returns the existing job (200) instead of creating a duplicate.

Parameters:

  • queueName (path) (required): string — The queue name (URL-safe)

Request body:

  • payload: object (required) — Arbitrary JSON object delivered as-is to your webhook. SimpleQ does not inspect or validate the contents.
  • idempotencyKey: string — Optional key for deduplication. Publishing twice with the same key returns the original job instead of creating a duplicate.
  • delay: number — Delay delivery by this many seconds (max 86400 = 24h). Decimals allowed.

Responses:

  • 200: Idempotent hit — existing job returned
  • 201: Job created
  • 400: Validation error
  • 402: Free-plan monthly attempt limit reached — publishing resumes next cycle or after upgrading. Never sent to paid plans.
  • 404: Queue not found

GET /v1/jobs/{id}

Get job status

Parameters:

  • id (path) (required): string — Job ID

Responses:

  • 200: Job document
  • 404: Job not found

Queues

Create queues and manage their config.

GET /v1/queues

List queues

Responses:

  • 200: Array of queues (signingSecret omitted)

POST /v1/queues

Create a queue Creates a queue and generates a signingSecret (returned once on creation). Supports named templates that prefill defaults: anthropic, openai. Explicit fields override template values.

Request body:

  • name: string (required)
  • webhookUrl: string (required)
  • maxAttempts: integer
  • maxDefers: integer
  • concurrency: integer
  • dlqEnabled: boolean
  • mode: string (standard | ack)
  • rateLimitMax: integer | null
  • rateLimitWindow: number
  • ackTimeout: number
  • ackTimeoutAction: string (retry | dead)
  • backoffType: string (fixed | exponential)
  • backoffDelay: number
  • template: string (anthropic | openai) — Optional. Prefills queue defaults from a named template. Explicit fields override the template values.

Responses:

  • 201: Queue created (signingSecret included)
  • 400: Validation error
  • 403: Plan limit exceeded (maxAttempts/maxDefers ceiling or queue count cap)

GET /v1/queues/{id}

Get a queue

Parameters:

  • id (path) (required): string — Queue ID

Responses:

  • 200: Queue (signingSecret omitted)
  • 404: Queue not found

PUT /v1/queues/{id}

Update queue config Partial update. name cannot be changed after creation.

Parameters:

  • id (path) (required): string — Queue ID

Request body:

  • webhookUrl: string
  • maxAttempts: integer
  • maxDefers: integer
  • concurrency: integer
  • dlqEnabled: boolean
  • mode: string (standard | ack)
  • rateLimitMax: integer | null
  • rateLimitWindow: number
  • ackTimeout: number
  • ackTimeoutAction: string (retry | dead)
  • backoffType: string (fixed | exponential)
  • backoffDelay: number

Responses:

  • 200: Updated queue (signingSecret omitted — it is returned only on creation)
  • 400: Validation error
  • 403: Plan limit exceeded (maxAttempts/maxDefers ceiling)
  • 404: Queue not found

DELETE /v1/queues/{id}

Delete a queue Deletes a queue. The queue stops accepting new jobs and the name becomes available to re-use immediately. Existing jobs remain retrievable by job ID for inspection.

Parameters:

  • id (path) (required): string — Queue ID

Responses:

  • 204: Queue deleted
  • 404: Queue not found

GET /v1/queues/{id}/jobs

List jobs in a queue

Parameters:

  • id (path) (required): string — Queue ID
  • page (query): integer [default 1, min 1]
  • limit (query): integer [default 25, min 1, max 100]
  • status (query): string (pending | processing | awaiting_ack | completed | dead)

Responses:

  • 200: Paginated jobs
  • 404: Queue not found

DLQ

Inspect and retry dead-lettered jobs.

GET /v1/queues/{id}/dlq

List dead-letter jobs

Parameters:

  • id (path) (required): string — Queue ID
  • page (query): integer [default 1, min 1]
  • limit (query): integer [default 25, min 1, max 100]
  • includeReplayed (query): boolean | null

Responses:

  • 200: Paginated DLQ entries
  • 404: Queue not found
  • 410: Queue has been deleted; its dead-letter jobs are gone

POST /v1/queues/{id}/dlq/{jobId}/replay

Replay a dead-lettered job

Parameters:

  • id (path) (required): string — Queue ID
  • jobId (path) (required): string — DLQ entry ID

Responses:

  • 201: New job created from DLQ entry
  • 402: Free-plan monthly attempt limit reached — replays mint new billable jobs, so they share the publish gate. Never sent to paid plans.
  • 404: Queue or DLQ job not found
  • 409: DLQ job already replayed
  • 410: Queue has been deleted; its dead-letter jobs are gone

POST /v1/queues/{id}/dlq/replay

Bulk replay DLQ jobs Retries up to 1000 DLQ jobs at once. Provide either jobIds: string[] or all: true.

Parameters:

  • id (path) (required): string — Queue ID

Responses:

  • 200: Bulk replay result
  • 400: Validation error
  • 402: Free-plan monthly attempt limit reached — replays mint new billable jobs, so they share the publish gate. Never sent to paid plans.
  • 404: Queue not found
  • 410: Queue has been deleted; its dead-letter jobs are gone

Ack mode

Async acknowledgement, defer, and nack for long-running or backpressured consumers.

POST /v1/jobs/{id}/ack

Acknowledge a job (ack-mode queues only) Signals successful completion of a job in awaiting_ack. Only valid for queues with mode: "ack".

Parameters:

  • id (path) (required): string — Job ID

Responses:

  • 200: Ack accepted
  • 400: Job is not awaiting ack, or queue does not use ack mode
  • 404: Job not found

POST /v1/jobs/{id}/nack

Signal failure for a job (ack-mode queues only) Marks an awaiting_ack job as failed. retryable: true re-queues with backoff; retryable: false dead-letters immediately.

Parameters:

  • id (path) (required): string — Job ID

Request body:

  • retryable: boolean
  • reason: string

Responses:

  • 200: Nack accepted
  • 400: Validation error, job not awaiting ack, or queue not in ack mode
  • 404: Job not found

POST /v1/jobs/{id}/defer

Apply backpressure (ack-mode queues only) Holds an awaiting_ack job for retryAfter seconds, then redelivers — without burning an attempt. Use when a downstream returns 429/503/529.

Parameters:

  • id (path) (required): string — Job ID

Request body:

  • retryAfter: number (required)
  • reason: string

Responses:

  • 200: Defer accepted
  • 400: Validation error, job not awaiting ack, or queue not in ack mode
  • 404: Job not found