Button · AsyncAPI Specification

Usebutton Webhooks

Version

View Spec View on GitHub CommerceMobile CommerceAffiliateAttributionDeep LinkingOffersPublishersRetailAsyncAPIWebhooksEvents

AsyncAPI Specification

Raw ↑
generated: '2026-07-21'
method: searched
source: https://developer.usebutton.com/docs/button-webhooks.md, https://developer.usebutton.com/docs/webhook-semantics.md
type: Webhooks
spec_type: none
notes: Button publishes no AsyncAPI document; this artifact captures the documented webhook surface verbatim from the developer docs.
webhooks:
  provider: Button
  transport: HTTPS POST (JSON body) to a publisher-configured URL
  management: Configured, edited, paused, and resumed in the Button Dashboard (https://app.usebutton.com/webhooks)
  docs:
    - https://developer.usebutton.com/docs/button-webhooks
    - https://developer.usebutton.com/docs/webhook-semantics
  security:
    scheme: HMAC-SHA256 signature of the raw request body using a per-webhook secret
    header: X-Button-Signature
    secret_location: Button Dashboard, per-webhook secret (https://app.usebutton.com/webhooks)
    verification_helpers:
      - library: button-client-node
        method: isWebhookAuthentic
        url: https://github.com/button/button-client-node#iswebhookauthentic
      - library: button-client-python
        method: is_webhook_authentic
        url: https://github.com/button/button-client-python#is_webhook_authentic
      - library: button-client-ruby
        method: webhook_authentic
        url: https://github.com/button/button-client-ruby#webhook_authentic
    receiver_tls: Receiver must present a full TLS chain to a well-known CA; Button's dispatchers do not support the Authority Information Access extension (RFC 5280 4.2.2.1)
  envelope:
    fields:
      - name: request_id
        description: Unique identifier of a request attempt, even when retrying a failed request (attempt-XXX)
      - name: id
        description: Unique identifier for the webhook event (hook-XXX); never reused, safe to dedupe on
      - name: event_type
        description: The state the transaction event represents
      - name: data
        description: The order details represented as a Transaction object
    headers:
      - name: Content-Type
        value: application/json
      - name: User-Agent
        value: Button Webhooks X.X.X
      - name: X-Button-Signature
        value: hex HMAC-SHA256 of raw body
  events:
    - name: tx-pending
      mutable: true
      billable: false
      description: Transaction created but not final; can still be adjusted or canceled. Commission not yet guaranteed. If the button_order_id already exists in your system, the webhook is reporting an order adjustment.
    - name: tx-validated
      mutable: false
      billable: true
      description: Finalization period concluded; transaction is immutable, commission in data.amount is final and billable to the Brand.
    - name: tx-declined
      mutable: false
      billable: false
      description: Transaction cancelled by the user or the Brand; never modified beyond this point and not billable.
  event_categories:
    - name: new-user-order
      description: Commission driven by an order event. No relation to user segment.
    - name: app-install
      description: Commission driven by the installation of the Brand application. Filter these out when rewarding purchases - app stores prohibit rewarding users for installs; app-install events skip the pending state.
  delivery:
    guarantee: at-least-once; dedupe on webhook id
    ordering: Ordered per transaction (next event for a transaction only sent after the current one is acknowledged); independent transactions delivered concurrently
    acknowledgment: Respond 2XX; 200/204 accepted and processed, 202 accepted but processing unsuccessful, 400 invalid (never re-sent), 401 invalid signature (re-sent)
    retries: Exponential back-off for the first hour, then hourly, for up to 3 days; a 400 response stops retries
    auto_pause: Endpoint automatically paused when >10% of webhooks attempted in the past hour failed (minimum 5 failures); Button emails the organization, collects new webhooks, and redelivers on resume
  payload_semantics:
    - All financial values are integers in the smallest currency unit (100 for $1.00, 500 for £5.00, 100 for JPY 100)
    - order_total is the order value; amount is the commission amount
    - Zero-dollar line items (samples, rewards) and negative line items (flat-rate or percentage discounts) appear in order_line_items; do not depend on their identifier/description structure
    - Button may add fields at any time; validate only the specific fields you need, never the full schema
  example:
    id: hook-xxxxxxxxxxxxxxxx
    event_type: tx-validated
    request_id: attempt-xxxxxxxxxxxxxxxxx
    data:
      id: tx-xxxxxxxxxxxxxxxx
      status: validated
      category: new-user-order
      amount: 100
      currency: USD
      order_total: 1000
      order_currency: USD
      btn_ref: srctok-xxxxxxxxxxxxxxxx
      button_order_id: btnorder-xxxxxxxxxxxxxxxx
      publisher_organization: org-xxxxxxxxxxxxxxxx
      commerce_organization: org-xxxxxxxxxxxxxxxx
      account_id: acc-xxxxxxxxxxxxxxxx
      publisher_customer_id: publisher_user_id_123
      pub_ref: publisher_pub_ref_123
      order_click_channel: app