1. Authentication and Base URL
All webhook management endpoints live in the Paywalls API and require theAuthorization: Bearer <PAYWALL_SECRET> header. Use the secret for the paywall
you want to subscribe on behalf of. Requests without a valid key return 401.
Unless stated otherwise, example requests assume the API base URL is
https://api.paywalls.ai.
2. Managing Subscriptions
2.1 Create a subscription
url– HTTPS endpoint that will receive deliveries.events– array of event names. Use the wildcard["*"]to receive everything. The wildcard cannot be mixed with other names.description– optional, trimmed to 512 chars.customHeaders– optional object of additional headers, max 10 entries.secret– optional pre-shared secret. If omitted, one is generated.
Returns the subscription without the full secret, except on creation where the secret is included once:
⚠️ Store thesecretsecurely. It is only returned on creation; subsequent reads showsecretSuffixfor diagnostics.
2.2 List subscriptions
- Optional
statusfilter (activeorinactive). The default returns both.
2.3 Fetch a single subscription
2.4 Deactivate a subscription
isActive: false) so you can re-enable
them later via PATCH /v1/webhooks/subscriptions/{id} (not yet exposed via the
REST surface).
3. Inspecting Delivery Logs
Each log entry includes delivery metadata (
id, status, retries, timing) and
the original event payload to help with debugging.
4. Delivery Payloads
When a webhook fires, we POST the following JSON document to yoururl:
4.1 HTTP headers
Each delivery includes signature headers so you can validate authenticity:
Verification steps
- Retrieve the subscription secret used for the delivery.
- Compute
HMAC_SHA256(secret, raw_request_body)and hex-encode it. - Compare to
X-Paywalls-Signatureusing a constant-time comparison. - Optionally ensure
X-Paywalls-Timestampis within an acceptable window (e.g. 5 minutes) to guard against replay attacks.
4.2 Example: Validate signatures in JavaScript
The snippet below shows a simple Node.js route that validates Grindery Paywalls signatures using the shared secret. It assumes you are using Express and have access to the raw request body.
Make sure your framework exposes the raw request body (Express requires enabling the verify option on the JSON body parser or a raw-body middleware).
5. Delivery Semantics & Retries
- Deliveries default to 30-second base backoff with jitter and double on each retry (configurable via environment variables).
- We retry up to
WEBHOOK_MAX_ATTEMPTS(defaults to 8). Non-retryable status codes (400,401,403,404,410,422) end the delivery immediately with an error.
6. Event Catalog
Events are grouped into categories. The tables below list the event key, description, and payload fields that appear underevent.data.
6.1 Paywall lifecycle
Paywall creation does not emit a webhook because subscriptions can only be configured after a paywall exists.
6.2 Integrations
6.3 User authorization
6.4 Balances & funds
6.5 Charges & usage
6.6 Payments (Stripe)
6.7 Proxy events
7. Next Steps
- Rotate webhook secrets periodically and update your consumer accordingly.
- Monitor
/v1/webhooks/logsfor failed deliveries; retry or investigate issues surfaced via the webhook delivery logs API. - Use the event catalog to build targeted reactions rather than subscribing to
*when possible—smaller workloads mean faster, more reliable processing.