> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prava.space/llms.txt
> Use this file to discover all available pages before exploring further.

# Receiver examples

> Optional Node.js and Python examples for accepting signed webhook events.

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:

```json theme={null}
{
  "account_id": "ma_YOUR_APP",
  "environment": "sandbox",
  "secrets": ["whsec_YOUR_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.

```bash theme={null}
chmod 600 /absolute/path/webhook-config.json
export WEBHOOK_CONFIG_PATH=/absolute/path/webhook-config.json
export WEBHOOK_INBOX_PATH=/absolute/path/webhook-inbox.sqlite
```

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

<Tabs>
  <Tab title="Node.js">
    The [Node.js receiver source](https://github.com/Prava-Payments/prava-docs/blob/main/examples/webhooks/receiver.mjs) 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:

    ```bash theme={null}
    node receiver.mjs
    ```
  </Tab>

  <Tab title="Python">
    The [Python receiver source](https://github.com/Prava-Payments/prava-docs/blob/main/examples/webhooks/receiver.py) uses **Python 3** and its standard library, including SQLite. No third-party packages are required.

    Run the downloaded file:

    ```bash theme={null}
    python3 receiver.py
    ```
  </Tab>
</Tabs>

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](/webhooks/testing#advanced-automated-sandbox-receiver).

[Verify signatures](/webhooks/security) · [Test your integration](/webhooks/testing) · [Delivery and recovery](/webhooks/delivery)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.