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

# List recent deliveries

> Returns the last **90 days** of delivery attempts for this endpoint, newest first. One row per attempt including retries - high volume; use `limit=100` to drain faster.

Filters: `status` (`pending` / `delivered` / `retrying` / `failed`), `event_type` (catalog name), and `created_after`/`created_before` (unix seconds, inclusive - matches this row's `created_at`). Compose with cursors.

Common pattern - audit all failures: `?status=failed&limit=100`, follow `starting_after` until `has_more=false`. Each failed row carries the last `response_code` your receiver returned. Replay a failed delivery with `POST /v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry`, which enqueues a fresh attempt (a new delivery row).

Scope: `webhooks:read`.

There is intentionally no `GET /v1/webhook_endpoints/{id}/deliveries/{delivery_id}` - a single delivery is only reachable by paging this list (or via POST .../retry, which returns the new attempt). Do not build an integration that expects a single-delivery fetch. Only real event deliveries appear here. Test sends from `POST /v1/webhook_endpoints/{id}/test` are synchronous and create no delivery row, so an empty list right after a successful test send is expected, not a fault.



## OpenAPI

````yaml /openapi.json get /v1/webhook_endpoints/{id}/deliveries
openapi: 3.1.0
info:
  title: VEXiON cards Public API
  description: >-
    ## Rate limiting


    Two independent layers, checked in this order:


    1. **Per-IP throttle (pre-authentication).** Applied to every `/v1` request
    BEFORE the API key is checked, keyed on the caller's IP address:
       - **600 requests/minute** per IP - a flood ceiling, `429 rate_limit_error` / `rate_limited`.
       - **20 failed authentications per 15 minutes** per IP - a key-guessing ceiling. Only responses that are `401` (missing/invalid/revoked key) count against this ceiling; a `403` from a valid key that simply lacks a scope does not. `429 rate_limit_error` / `too_many_failed_attempts`.

       Both ceilings send `Retry-After` (seconds).
    2. **Per-key, per-bucket limiter (post-authentication).** Documented per
    endpoint (see each operation's `429` response and the `rate_limit` field on
    the API Key resource) - e.g. 60/min default, 120/min for transactions, plus
    the notification-broadcast and lookup-filter buckets described on their own
    endpoints.


    ### Rate-limit response headers


    Every rate-limited response carries the legacy `X-RateLimit-Limit` /
    `X-RateLimit-Remaining` / `X-RateLimit-Reset` family (the last is an **epoch
    timestamp**) AND the IETF standards-track headers, side by side:


    - `RateLimit-Policy: "<bucket>";q=<quota>;w=<window seconds>` - the static
    policy for the bucket that was hit.

    - `RateLimit: "<bucket>";r=<remaining>;t=<seconds until reset>` - live
    state. **`t` is a DURATION (seconds remaining), not the epoch timestamp
    `X-RateLimit-Reset` carries - the two are never the same value.**
  version: 1.0.0
servers:
  - url: https://api.vexioncards.one
    description: Production
  - url: https://migration.api.vexioncards.one
    description: Sandbox
security:
  - apiKey: []
tags:
  - name: Customers
  - name: Cards
  - name: Transactions
  - name: Notifications
  - name: Locations
  - name: Products
  - name: API keys
  - name: Organization
  - name: Webhook endpoints
  - name: Events
  - name: Custom fields
  - name: Team members
  - name: Icons
paths:
  /v1/webhook_endpoints/{id}/deliveries:
    get:
      tags:
        - Webhook endpoints
      summary: List recent deliveries
      description: >-
        Returns the last **90 days** of delivery attempts for this endpoint,
        newest first. One row per attempt including retries - high volume; use
        `limit=100` to drain faster.


        Filters: `status` (`pending` / `delivered` / `retrying` / `failed`),
        `event_type` (catalog name), and `created_after`/`created_before` (unix
        seconds, inclusive - matches this row's `created_at`). Compose with
        cursors.


        Common pattern - audit all failures: `?status=failed&limit=100`, follow
        `starting_after` until `has_more=false`. Each failed row carries the
        last `response_code` your receiver returned. Replay a failed delivery
        with `POST /v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry`,
        which enqueues a fresh attempt (a new delivery row).


        Scope: `webhooks:read`.


        There is intentionally no `GET
        /v1/webhook_endpoints/{id}/deliveries/{delivery_id}` - a single delivery
        is only reachable by paging this list (or via POST .../retry, which
        returns the new attempt). Do not build an integration that expects a
        single-delivery fetch. Only real event deliveries appear here. Test
        sends from `POST /v1/webhook_endpoints/{id}/test` are synchronous and
        create no delivery row, so an empty list right after a successful test
        send is expected, not a fault.
      operationId: listWebhookDeliveries
      parameters:
        - name: id
          in: path
          description: Endpoint identifier (`whk_` prefix).
          required: true
          example: whk_4crd3hu6mm2nydl7yhaji24dii
          schema:
            type: string
            pattern: ^whk_[A-Za-z0-9]+$
        - name: status
          in: query
          description: 'Filter: `pending`, `delivered`, `retrying`, `failed`.'
          required: false
          schema:
            type: string
            enum:
              - pending
              - retrying
              - delivered
              - failed
        - name: event_type
          in: query
          description: Filter by catalog event name.
          required: false
          schema:
            $ref: '#/components/schemas/WebhookEventName'
        - name: created_after
          in: query
          description: Only delivery attempts created at or after this time (inclusive).
          required: false
          schema:
            anyOf:
              - type: integer
                title: Unix seconds
              - type: string
                format: date-time
                title: ISO-8601
        - name: created_before
          in: query
          description: Only delivery attempts created at or before this time (inclusive).
          required: false
          schema:
            anyOf:
              - type: integer
                title: Unix seconds
              - type: string
                format: date-time
                title: ISO-8601
        - name: limit
          in: query
          required: false
          description: Page size, 1-100. Default 25.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - name: starting_after
          in: query
          description: >-
            Walk forward. Send the last id from the previous page's data[].
            Numeric offset or page parameters are not supported; cursors are the
            only supported paging mechanism.
          required: false
          schema:
            type: string
        - name: ending_before
          in: query
          required: false
          description: Reverse cursor - returns deliveries before this `whd_` id.
          schema:
            type: string
            pattern: ^whd_[A-Za-z0-9]+$
      responses:
        '200':
          description: The delivery record object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDeliveryList'
              examples:
                Mixed statuses:
                  summary: Delivered + retrying rows
                  value:
                    object: list
                    data:
                      - id: whd_01HW9RCZ4HJ7N8MTX1RVWHDDEF
                        object: webhook_delivery
                        webhook_endpoint_id: whk_01HW9RBZ4GH7N8MTX1RVWHKDEF
                        event_id: evt_01HW9RDZ4JK7N8MTX1RVEVTDEF
                        event_type: transaction.created
                        status: delivered
                        response_code: 200
                        attempts: 1
                        next_retry_at: null
                        delivered_at: 1750691720
                        created_at: 1750691720
                      - id: whd_01HW9RCZ4HJ7N8MTX1RVWHDDEG
                        object: webhook_delivery
                        webhook_endpoint_id: whk_01HW9RBZ4GH7N8MTX1RVWHKDEF
                        event_id: evt_01HW9RDZ4JK7N8MTX1RVEVTDEH
                        event_type: customer.pass_installed
                        status: retrying
                        response_code: 502
                        attempts: 4
                        next_retry_at: 1750691910
                        delivered_at: null
                        created_at: 1750691600
                    has_more: true
                    url: >-
                      /v1/webhook_endpoints/whk_01HW9RBZ4GH7N8MTX1RVWHKDEF/deliveries
                Failed only:
                  summary: '?status=failed audit'
                  value:
                    object: list
                    data:
                      - id: whd_01HW9RCZ4HJ7N8MTX1RVWHDFL1
                        object: webhook_delivery
                        webhook_endpoint_id: whk_01HW9RBZ4GH7N8MTX1RVWHKDEF
                        event_id: evt_01HW9RDZ4JK7N8MTX1RVEVTFL1
                        event_type: transaction.created
                        status: failed
                        response_code: 503
                        attempts: 12
                        next_retry_at: null
                        delivered_at: null
                        created_at: 1750604200
                    has_more: false
                    url: >-
                      /v1/webhook_endpoints/whk_01HW9RBZ4GH7N8MTX1RVWHKDEF/deliveries
          headers: {}
        '400':
          description: >-
            Invalid pagination or filter parameter: limit outside 1-100, a
            malformed cursor, or an unparseable created_after/created_before
            date.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                Invalid limit:
                  summary: limit out of range
                  value:
                    error:
                      type: invalid_request_error
                      code: invalid_limit
                      message: limit must be an integer between 1 and 100.
                      doc_url: >-
                        https://vexioncards.mintlify.site/api-reference/errors#invalid_limit
                      request_id: req_5f8b2c4a9e1d3
                      param: limit
                Invalid date:
                  summary: unparseable date filter
                  value:
                    error:
                      type: invalid_request_error
                      code: invalid_date
                      message: >-
                        created_after must be a unix timestamp or an ISO 8601
                        date-time. Got 'not-a-date'.
                      doc_url: >-
                        https://vexioncards.mintlify.site/api-reference/errors#invalid_date
                      request_id: req_5f8b2c4a9e1d4
                      param: created_after
        '401':
          description: Missing, invalid, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Key lacks the required scope (webhooks:read).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Resource not found in your organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited - respect Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error. Retry-safe on idempotent calls.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: >-
                    An internal error occurred. The request may be retried with
                    the same Idempotency-Key.
                  doc_url: >-
                    https://vexioncards.mintlify.site/api-reference/errors#internal_error
                  request_id: req_5f8b2c4a9e1d3
              examples:
                Http 500 default:
                  summary: Http 500 default
                  value:
                    error:
                      type: api_error
                      code: internal_error
                      message: >-
                        An internal error occurred. The request may be retried
                        with the same Idempotency-Key.
                      doc_url: >-
                        https://vexioncards.mintlify.site/api-reference/errors#internal_error
                      request_id: req_5f8b2c4a9e1d3
          headers: {}
      deprecated: false
components:
  schemas:
    WebhookEventName:
      type: string
      enum:
        - customer.created
        - customer.updated
        - customer.deleted
        - customer.pass_installed
        - customer.pass_uninstalled
        - card.created
        - card.updated
        - card.deleted
        - custom_field.created
        - custom_field.updated
        - custom_field.deleted
        - product.created
        - product.updated
        - transaction.created
        - transaction.reversed
        - notification.sent
        - notification.delivery_updated
        - location.updated
        - team_member.added
        - team_member.updated
        - team_member.removed
        - webhook_endpoint.delivery_failed
      description: >-
        The locked v1 event catalog - 22 events across 9 subjects. Names follow
        `resource.action` with past-participle actions (`transaction.created`),
        never the dotted verb-stems used by transaction types - the two
        vocabularies never mix. `product.created`/`product.updated` fire for
        dashboard and API-created catalog changes; POS-synced catalog changes do
        not emit (they mirror the till, and a first sync would flood your
        endpoint).
      example: transaction.created
    WebhookDeliveryList:
      allOf:
        - $ref: '#/components/schemas/ListEnvelope'
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/WebhookDelivery'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - rate_limit_error
                - idempotency_error
                - api_error
            code:
              type: string
            message:
              type: string
            retry_after:
              type: integer
              description: >-
                Seconds to wait before retrying. Present on rate-limit (429)
                errors and on the retryable 409 conflicts
                (`idempotency_key_in_use`, `create_in_progress`,
                `concurrent_update`); mirrors the `Retry-After` HTTP header.
                Absent on error types that carry no retry guidance.
              example: 5
            param:
              type:
                - string
                - 'null'
            request_id:
              type: string
            doc_url:
              type: string
              format: uri
            field_errors:
              type: array
              description: >-
                Per-field errors on a 422. At most 100 entries: a request with
                more errors gets the first 100.
              items:
                type: object
                properties:
                  param:
                    type: string
                  code:
                    type: string
                  message:
                    type: string
                  expected_currency:
                    type: string
                    description: >-
                      On `currency_mismatch`: the business currency the request
                      must use. Absent on every other field error.
          description: >-
            The error payload: type (category), code (machine-readable), message
            (human-readable), retry_after (seconds, on rate-limit errors and
            retryable 409 conflicts only), param (offending field), request_id,
            doc_url, field_errors[].
      description: >-
        Standard error envelope. Branch on `error.code`; include
        `error.request_id` in support requests. See the Errors guide.
    ListEnvelope:
      type: object
      required:
        - object
        - data
        - has_more
      properties:
        object:
          type: string
          const: list
          description: Always `"list"`.
        data:
          type: array
          items: {}
          description: Array of the requested resource type.
        has_more:
          type: boolean
          description: >-
            True when more pages exist - pass the last item id as
            `starting_after`.
        next_cursor:
          type:
            - string
            - 'null'
          description: >-
            Cursor for the next page **in the direction you are already
            paging**, or `null` when this page ends the collection. `has_more:
            true` always comes with a non-null `next_cursor`.


            Feed it back to the SAME parameter you used: `starting_after` when
            paging forward (the default), or `ending_before` when paging
            backward. Treat it as opaque and do not parse it.


            You no longer need to take the last object's `id` yourself. That
            still works and is unchanged, but deriving the cursor from the page
            put the burden of knowing the sort direction on you, and it broke
            silently on any endpoint whose cursor is not the object id.
          example: cus_iofv5j4hn6bphinmmyat27tc5y
        url:
          type: string
          description: Stable collection URL.
      description: >-
        Standard cursor-pagination envelope for list endpoints. See the
        Pagination guide.
    WebhookDelivery:
      type: object
      description: >-
        One delivery attempt record. Retained 90 days. High-volume listing: one
        row per attempt including retries. We store the response STATUS CODE
        only. No response headers, no response body bytes, and no request-body
        hash are retained, by design: see the privacy note in the Webhooks
        guide. Each attempt records its number, timestamp, status code, error
        string and duration. Replay is available over the API: POST
        /v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry. There is
        intentionally no single-delivery GET-by-id endpoint - list + retry only.
      required:
        - id
        - object
        - webhook_endpoint_id
        - event_id
        - event_type
        - status
        - attempts
        - created_at
      properties:
        id:
          type: string
          pattern: ^whd_[A-Za-z0-9]+$
          description: Delivery record id (`whd_` prefix). Used as the pagination cursor.
          example: whd_01HW9RCZ4HJ7N8MTX1RVWHDDEF
        object:
          type: string
          const: webhook_delivery
          description: Always `"webhook_delivery"`.
        webhook_endpoint_id:
          type: string
          description: The endpoint this delivery targeted.
          example: whk_01HW9RBZ4GH7N8MTX1RVWHKDEF
        event_id:
          type: string
          pattern: ^evt_[A-Za-z0-9]+$
          description: >-
            The event ULID - stable across retries; your receiver deduplicates
            on this.
          example: evt_01HW9RDZ4JK7N8MTX1RVEVTDEF
        event_type:
          $ref: '#/components/schemas/WebhookEventName'
        status:
          type: string
          enum:
            - pending
            - delivered
            - retrying
            - failed
          description: >-
            `delivered` = receiver returned 2xx within 10 s. `retrying` = on the
            backoff curve. `failed` = all 12 attempts exhausted (also fires
            `webhook_endpoint.delivery_failed` to other subscribed endpoints).
          example: delivered
        response_code:
          type:
            - integer
            - 'null'
          description: >-
            HTTP status the receiver returned on the most recent attempt. Null
            when the attempt never got a response (timeout, TCP/TLS error).
          example: 200
        attempts:
          type: integer
          description: Attempt count so far (max 12 across 24 hours).
          example: 1
        next_retry_at:
          type:
            - integer
            - 'null'
          description: >-
            Unix seconds of the next scheduled attempt. Null when delivered or
            failed.
          example: null
        delivered_at:
          type:
            - integer
            - 'null'
          description: Unix seconds of successful delivery. Null otherwise.
          example: 1750691720
        created_at:
          type: integer
          description: Unix seconds when the event was first dispatched to this endpoint.
          example: 1750691720
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        Your secret API key as a Bearer token: `Authorization: Bearer
        vxn_sk_...`. Keys are created and scoped in the dashboard - see
        [Authentication](/api-reference/introduction#authentication).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.