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

# Delete up to ten leased messages



## OpenAPI

````yaml /api-reference/specs/queue.yaml post /v1/queues/{queue_id}/messages/delete-batch
openapi: 3.0.3
info:
  title: Basaltic Queue API
  version: 1.0.0
  description: |
    Durable message queues with at-least-once delivery.

    **A receive is a lease, not a read.** `ReceiveMessage` hides the
    messages it returns for the queue's visibility timeout and hands back
    a *receipt handle*. The message comes back — to you or to another
    consumer — unless you delete it with that handle before the lease
    lapses. Everything else follows from this: a consumer that crashes
    mid-work loses nothing, and a message no consumer can process is
    caught by `receive_count` crossing the redrive threshold.

    **Receipt handles are per-lease, not per-message.** A new one is
    minted on every receive. Presenting a handle from a lease that has
    already lapsed fails with `QUEUE_RECEIPT_HANDLE_EXPIRED` rather than
    deleting a message that has since been handed to someone else — so a
    slow consumer finds out it was slow instead of silently destroying
    another's work.

    **Two kinds of queue, fixed at creation.** A *standard* queue
    delivers at least once with best-effort ordering and races
    consumers freely. A *FIFO* queue — whose name must end in `.fifo` —
    delivers strictly in order within a `message_group_id` and refuses
    to hand out a group's next message while an earlier one is still in
    flight; sends inside a five-minute window that repeat a
    `message_deduplication_id` collapse to one message. Ordering across
    groups is undefined, which is what lets groups run concurrently. The
    kind cannot be changed: a queue holding messages written under one
    set of rules cannot start honouring the other.

    **Long polling.** `wait_time_seconds` (up to 20) blocks the receive
    until a message arrives rather than returning empty immediately. It
    costs one request instead of the many an empty polling loop would
    make, and it returns as soon as a producer sends.

    **Message bodies are encrypted at rest.** Each queue has a data key
    that seals its messages; that key is itself wrapped by a platform key
    or, if you set `kms_key_id`, by your own. The unwrapped data key is
    cached for `kms_data_key_reuse_period_seconds` — so for up to that
    long after you disable your key, sends and receives on the queue keep
    working. Lower it to tighten that window at the cost of more KMS
    round-trips.
  contact:
    name: Basaltic Support
    email: ping@basaltic.sh
  license:
    name: Proprietary
    url: https://basaltic.sh/terms
servers:
  - url: https://queue.{region}.basaltic.sh
    description: Regional API endpoint
    variables:
      region:
        default: sa-saopaulo-1
        description: Region code
security:
  - SignatureAuth: []
tags:
  - name: Queues
    description: Queue lifecycle and attributes
  - name: Messages
    description: Sending, receiving, and acknowledging messages
paths:
  /v1/queues/{queue_id}/messages/delete-batch:
    parameters:
      - $ref: '#/components/parameters/QueueId'
    post:
      tags:
        - Messages
      summary: Delete up to ten leased messages
      operationId: deleteMessageBatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteMessageBatchRequest'
      responses:
        '200':
          description: Per-entry results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    QueueId:
      name: queue_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
        example: a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d
  schemas:
    DeleteMessageBatchRequest:
      type: object
      required:
        - entries
      properties:
        entries:
          type: array
          minItems: 1
          maxItems: 10
          items:
            type: object
            required:
              - id
              - receipt_handle
            properties:
              id:
                type: string
                example: e1
              receipt_handle:
                type: string
                example: >-
                  019400aabbbb7ccc8dddeeeeffff00003f2a91c4d5e60718293a4b5c6d7e8f9015a6b7c8d9e0f1a2b3c4d5e6f708192a3
    BatchResponse:
      type: object
      required:
        - results
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/BatchResult'
    BatchResult:
      type: object
      required:
        - id
      properties:
        id:
          type: string
          description: The entry id from the request.
          example: e1
        message_id:
          type: string
          format: uuid
          example: 019400aa-bbbb-7ccc-8ddd-eeeeffff0000
        duplicate:
          type: boolean
          example: false
        error:
          type: string
          description: Machine-readable code when this entry failed.
          example: QUEUE_MESSAGE_TOO_LARGE
        message:
          type: string
          description: Human-readable reason accompanying error.
          example: message is 300000 bytes; this queue accepts 262144
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: Error code identifying the type of error
              example: INVALID_INPUT
            message:
              type: string
              description: Human-readable error message
              example: Invalid request parameters
            request_id:
              type: string
              format: uuid
              description: Request ID for debugging
              example: 550e8400-e29b-41d4-a716-446655440000
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: INVALID_INPUT
              message: Invalid request parameters
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Unauthorized:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: UNAUTHORIZED
              message: Authentication required
              request_id: 550e8400-e29b-41d4-a716-446655440000
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: ACCESS_DENIED
              message: You don't have permission to perform this action
              request_id: 550e8400-e29b-41d4-a716-446655440000
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: NOT_FOUND
              message: Resource not found
              request_id: 550e8400-e29b-41d4-a716-446655440000
  securitySchemes:
    SignatureAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >
        Request signing with an access key issued to a service account. An

        HMAC-SHA256 over a canonical form of the request, close to AWS SigV4.

        The `basaltic` CLI signs for you.


        Send `Authorization`, `X-Date` (UTC, `YYYYMMDDTHHMMSSZ`) and `X-Nonce`

        (random per request); add `X-Content-Sha256` to bind a body, and

        `X-Amz-Security-Token` when using temporary credentials.


        ```

        Authorization: BASALTIC-HMAC-SHA256
        Credential=<access_key_id>/<date>/<region>/basaltic/basaltic_request,
        SignedHeaders=host;x-date;x-nonce, Signature=<hex>

        ```


        `<region>` is the region code you are calling, or `global` for the
        global

        services. A signature is valid for 5 minutes from `X-Date`, and mutating

        requests are replay-guarded on the nonce.


        **Full signing procedure, including a working implementation:**

        https://docs.basaltic.sh/authentication


        ## Rate limits

        There is no global request budget. A limit applies only where an

        operation documents a `429`, and that operation says what it counts.

        Those responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining`,

        `X-RateLimit-Reset` and, on a `429`, `Retry-After` — read them rather

        than hard-coding a number. Retrying before `Retry-After` is refused and

        extends the window. Everything else is bounded by quota, not by request

        rate.

````