> ## Documentation Index
> Fetch the complete documentation index at: https://headgate.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk retry/archive/delete/cancel. ASYNCHRONOUS by construction.

> asynq has RunAllScheduledTasks/DeleteAllRetryTasks/ArchiveAllPendingTasks and this
spec originally had no equivalent — retrying 100k jobs one HTTP call at a time is
not an API. A synchronous unbounded write is unsafe, so a bulk request
returns an operation to poll rather than blocking. Requires Idempotency-Key.




## OpenAPI

````yaml /api/headgate.openapi.yaml post /jobs/bulk
openapi: 3.1.0
info:
  title: headgate control API
  version: 0.1.0
  description: >
    The web UI is one client of this control API and gets no

    privileged access — asynqmon reads Redis directly, which is why its
    compatibility

    note is three minor versions stale.


    Both the Go and Rust implementations serve this spec, and the conformance
    suite

    asserts identical responses. Every list endpoint is bounded to prevent
    inspection

    from becoming an unbounded store operation: asynq's

    GetQueueInfo is O(number of groups) and has pinned Redis CPU for seconds in

    production. Monitoring caused the outage.


    DERIVED FROM THE ARCHITECTURE, NOT FROM A PREDECESSOR'S UI. The first draft
    of this

    spec was the asynq Inspector surface -- list by state, act on one job, pause
    a queue

    -- with new nouns bolted on. That inherited three problems: it omitted bulk

    operations, history, and enqueue (which asynq and apalis-board respectively
    DO have),

    and more importantly it had no endpoint for the question this system's own
    design

    creates. When dequeue is an admission decision, the operator's first
    question is not

    "what is in the queue" but "why is THIS job not running" -- see
    /jobs/{id}/admission.

    No predecessor needs that endpoint because no predecessor has a gate.
servers:
  - url: /api/v1
security: []
paths:
  /jobs/bulk:
    post:
      summary: Bulk retry/archive/delete/cancel. ASYNCHRONOUS by construction.
      description: >
        asynq has
        RunAllScheduledTasks/DeleteAllRetryTasks/ArchiveAllPendingTasks and this

        spec originally had no equivalent — retrying 100k jobs one HTTP call at
        a time is

        not an API. A synchronous unbounded write is unsafe, so a bulk request

        returns an operation to poll rather than blocking. Requires
        Idempotency-Key.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - action
                - selector
              properties:
                action:
                  type: string
                  enum:
                    - retry
                    - archive
                    - delete
                    - cancel
                selector:
                  type: object
                  description: >-
                    Same filters as GET /jobs. An empty selector is rejected —
                    no accidental delete-everything.
                  properties:
                    queue:
                      type: string
                    state:
                      $ref: '#/components/schemas/State'
                    kind:
                      type: string
                    partition_key:
                      type: string
                    older_than_ms:
                      type: integer
                dry_run:
                  type: boolean
                  default: false
                  description: Return the count that WOULD be affected.
      responses:
        '202':
          description: Bulk operation accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Operation'
        '400':
          description: Empty selector, or no Idempotency-Key.
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
      description: >
        Required on every mutating request. A double-clicked Retry, or a proxy
        retrying a

        POST, must not enqueue the job twice. Keys are retained long enough to
        cover a

        client retry window and the response is replayed verbatim.
  schemas:
    State:
      type: string
      enum:
        - pending
        - scheduled
        - available
        - running
        - retryable
        - completed
        - archived
        - cancelled
        - quarantined
        - undecodable
    Operation:
      type: object
      required:
        - id
        - status
        - affected
      properties:
        id:
          type: string
        status:
          type: string
          enum:
            - pending
            - running
            - completed
            - failed
        affected:
          type: integer
        total_estimated:
          type: integer
        dry_run:
          type: boolean
        error:
          type:
            - string
            - 'null'

````