Skip to main content
These examples are optional starting points for your server. Prava webhooks work with any backend language or framework. The runtime versions below are requirements for these example programs, not for the webhook API. Both examples use their language’s standard library to verify the signature on the raw request body, check the application and environment, echo verification challenges, and save events in SQLite before returning a successful response. A unique event-ID constraint prevents duplicate inbox entries.

Configure an example

Download the example for your preferred language using the source links below. Create a private configuration file outside your repository with the following structure. Replace the placeholders with your application ID and the endpoint’s signing secret:
Set its permissions to 0600 so only its owner can read or modify it. Point WEBHOOK_CONFIG_PATH to this file and WEBHOOK_INBOX_PATH to a private, durable SQLite file. The paths in these commands are placeholders; replace them with your local paths.
The whsec_... value is the webhook endpoint signing secret. Do not substitute an application API key, commit this file, or log its contents.

Run your preferred example

The Node.js receiver source is supported on Node.js 24 or later. It uses Node’s built-in SQLite module, so this complete example is not intended for older runtimes. This requirement does not apply to the JavaScript verification function or to your own receiver.Run the downloaded file:
Both examples listen at http://127.0.0.1:8787/webhooks by default. Set PORT to choose a different local port. Use a reverse proxy for your public HTTPS endpoint, or a temporary HTTPS tunnel for sandbox testing. Register the public URL in the dashboard; the local HTTP address is not a valid delivery destination.

Process stored events

A separate consumer reads unprocessed webhook_inbox records. In one application transaction, deduplicate side effects by event ID, ignore test: true for business effects, apply only a newer resource version, then set processed_at. For external side effects, use that service’s idempotency mechanism. A successful webhook response confirms receipt, not completion of your business processing. SQLite here demonstrates durable acceptance on a single host. For a receiver deployed across multiple hosts, use a shared production database or durable queue with equivalent deduplication. Leave WEBHOOK_E2E_CONTROL_KEY and WEBHOOK_E2E_ACCOUNT_ID unset for an ordinary receiver. Those options are only for automated sandbox tests. Verify signatures · Test your integration · Delivery and recovery