Skip to main content
When a payment on one of your invoices is confirmed on Base, Kibble sends an HTTP POST request to a URL you supply. This lets your backend react immediately — updating order records, triggering fulfillment, or sending receipts — without polling the API.
Webhooks are configured per invoice, not at the account level. Each invoice can have its own webhook_url.

How to configure a webhook

Pass a webhook_url when you create an invoice. Kibble generates a unique webhook_secret for that invoice and returns it in the API response.
npx create-kibble --stdin <<'EOF'
{
  "merchant_email": "you@example.com",
  "merchant_name": "Acme Corp",
  "merchant_address": "1 Market St, San Francisco, CA",
  "vendor_email": "vendor@example.com",
  "vendor_name": "Supplier Ltd",
  "line_items": [
    { "description": "Consulting services", "quantity": 1, "unit_price": "2500.00" }
  ],
  "due_date": "2026-05-31",
  "wallet_type": "privy",
  "webhook_url": "https://yourapp.example.com/webhooks/kibble"
}
EOF
The response includes a webhook_secret. Store it securely — you will need it to verify the signature on every incoming request.
{
  "invoice_id": "a1b2c3d4-...",
  "invoice_number": "INV-0001",
  "slug": "abc12345",
  "invoice_url": "https://pay.kibble.sh/i/abc12345",
  "deposit_address": "0xAbCd...",
  "total_amount": "2500.00",
  "webhook_secret": "Xk9mLqR3vN8pT2wY..."
}
The webhook_secret is returned only once, at creation time. It is never exposed again through the API. Treat it like a password.

What triggers a webhook

Kibble fires the webhook when on-chain payment activity changes the invoice status. The possible trigger states are:
Invoice statusMeaning
paidThe exact amount was received
partialA payment was received but it is below the invoice total
excessA payment was received that exceeds the invoice total
Kibble does not fire a webhook for draft or sent status changes.

Webhook payload

The POST body is a JSON object with the following fields:
{
  "invoice_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "invoice_number": "INV-0001",
  "status": "paid",
  "tx_hash": "0xabc123...",
  "paid_amount": "2500.0",
  "paid_at": "2026-04-28T14:23:01.000Z"
}
FieldTypeDescription
invoice_idstringUUID of the invoice
invoice_numberstringHuman-readable invoice number
statusstringNew invoice status: paid, partial, or excess
tx_hashstringOn-chain transaction hash
paid_amountstringUSDC amount received
paid_atstringISO 8601 timestamp of confirmation

Signature header

Every request includes an X-Kibble-Signature header. The value is the HMAC-SHA256 digest of the raw request body, prefixed with sha256=:
X-Kibble-Signature: sha256=3d5f2a...
Always verify this signature before trusting the payload. See Webhook verification for code examples.

Retry behavior

Kibble makes a single attempt to deliver each webhook. Your endpoint should return a 2xx response as quickly as possible. If processing takes time, acknowledge the request immediately and handle the work asynchronously.
Log the raw request body and X-Kibble-Signature header during development to make signature debugging easier.