← Back

Webhooks

Webhooks let you receive real-time HTTP notifications when shopping list items change. When an event occurs, Bring Bananas sends a POST request to your configured URL with the event payload.

Events

Event Trigger
item.created An item is added to a shopping list
item.updated An item is modified (name, note, or completion status)
item.deleted An item is removed from a shopping list

Events fire regardless of how the change was made — through the app, the API, or sync.

Payload Format

{
  "event": "item.created",
  "timestamp": "2026-02-27T14:30:00Z",
  "data": {
    "item_id": "a1b2c3d4-...",
    "shopping_list_id": "e5f6a7b8-...",
    "name": "Milk",
    "note": "2% fat",
    "completed_at": null
  }
}

Headers

Each delivery includes these headers:

Header Description
Content-Type application/json
X-Webhook-Event The event type (e.g. item.created)
X-Webhook-Signature HMAC-SHA256 hex digest of the request body, signed with your secret

Verifying Signatures

To verify a webhook is authentic, compute an HMAC-SHA256 of the raw request body using your secret and compare it to the X-Webhook-Signature header.

import hmac, hashlib

def verify(body: bytes, secret: str, signature: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

Retries

If your endpoint returns a non-2xx status code or is unreachable, Bring Bananas retries with exponential backoff:

Attempt Delay
1 30 seconds
2 2 minutes
3 8 minutes
4 32 minutes
5 ~2 hours

After 5 failed attempts the delivery is marked as failed and not retried.

Setup

You can manage webhooks from the Bring Bananas app under Settings. When creating a webhook you'll provide a URL, choose which events to subscribe to, and set a secret (minimum 16 characters). Save the secret — it's only shown once and is used to verify delivery signatures.