Webhooks
Realtime events for subscriptions, billing, and library changes.
Gummble sends webhooks for subscription lifecycle (via Polar), payment events, and library mutations. All deliveries are signed so you can verify origin without secret rotation drift.
Configuring an endpoint
Set your webhook URL in Settings → Webhooks on gummble.com.
We require:
https://only (no plaintext)- TLS 1.2+
- Endpoint returns
2xxwithin 10s, else we retry
Verifying signatures
Every delivery has:
X-Gummble-Signature: t=1779555000,v1=hex(sha256(t + "." + body, secret))
X-Gummble-Event: subscription.created
X-Gummble-Delivery: evt_01HXY...function verify(secret, header, rawBody) {
const [t, v1] = header.split(',').map(p => p.split('=')[1])
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex')
// timing-safe compare
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
&& (Date.now()/1000 - Number(t) < 300)
}Reject deliveries older than 5 minutes — replay protection.
Event types
| Event | Description |
|---|---|
subscription.created | New paid subscription started |
subscription.updated | Plan, renewal, or status changed |
subscription.canceled | User canceled (still active until period end) |
subscription.deleted | Subscription fully ended |
payment.succeeded | Stripe/Polar payment captured |
payment.failed | Payment attempt failed |
app.added | New app indexed in the library |
screen.added | New screen captured for an existing app |
Retry behaviour
Failed deliveries (non-2xx, timeout, TLS error) retry with exponential
backoff: 2m, 10m, 30m, 1h, 4h, 8h, 24h. After 7 failures the endpoint
is disabled and you get an email.