Skip to main content
Webhooks let you receive real-time notifications whenever something important happens inside a paywall. This guide walks through creating subscriptions, understanding deliveries, verifying signatures, and the catalog of events that can be emitted by the system.

1. Authentication and Base URL

All webhook management endpoints live in the Paywalls API and require the Authorization: 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.
Response (201)
Returns the subscription without the full secret, except on creation where the secret is included once:
⚠️ Store the secret securely. It is only returned on creation; subsequent reads show secretSuffix for diagnostics.

2.2 List subscriptions

  • Optional status filter (active or inactive). The default returns both.

2.3 Fetch a single subscription

2.4 Deactivate a subscription

Subscriptions are soft-deactivated (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

Query parameters: 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 your url:

4.1 HTTP headers

Each delivery includes signature headers so you can validate authenticity: Verification steps
  1. Retrieve the subscription secret used for the delivery.
  2. Compute HMAC_SHA256(secret, raw_request_body) and hex-encode it.
  3. Compare to X-Paywalls-Signature using a constant-time comparison.
  4. Optionally ensure X-Paywalls-Timestamp is 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 under event.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/logs for 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.