# Webhook Sender
Outbound signed webhooks
- Package: @bijectionhq/webhook-sender
- Category: Messaging
- Status: Preview
- License: MIT
- Bijection source (repository access required): https://github.com/bijectionhq/webhook-sender/tree/872d4ed78b85dd9ecec12b05823e0722fefbe437
- Upstream: https://github.com/TimpiaAI/convex-webhook-sender/tree/ebceea551dbe539145470fae0ed757d83ccaa0f1
- Documentation: https://docs.bijection.com/components/using
- Directory: https://bijection.com/components/webhook-sender
## Get the source
Bijection repository access is required. Request access at https://bijection.com/contact.
```sh
git clone https://github.com/bijectionhq/webhook-sender.git
cd webhook-sender
git checkout 872d4ed78b85dd9ecec12b05823e0722fefbe437
```
## Before using this component
Read the package README at the recorded revision for setup, dependencies, and API examples. Upstream documentation describes the original package and may differ from the Bijection adaptation. This is a source candidate for evaluation. Catalog inclusion does not establish npm availability or runtime qualification. Check compatibility with your SDK and deployment before adoption. External providers run their own compute.
## Upstream package documentation
Recorded 2026-10-23. This describes convex-webhook-sender; check the Bijection adaptation separately.
A Convex component that handles reliable outbound webhook delivery with HMAC-SHA256 signing, automatic retries with exponential backoff, and comprehensive delivery tracking. It provides a managed queue system that handles webhook failures, rate limiting, and provides full audit trails of delivery attempts. Developers get a production-ready webhook infrastructure without building retry logic, signature generation, or delivery monitoring from scratch.
### Use cases
• **E-commerce order notifications** - Send order status updates to third-party fulfillment services with guaranteed delivery and retry logic for failed attempts
• **User event streaming** - Notify external analytics platforms, CRMs, or marketing tools when users complete actions like signups or purchases
• **System integration webhooks** - Connect your Convex app to payment processors, notification services, or other SaaS tools that expect webhook callbacks
• **Multi-tenant webhook delivery** - Build SaaS products where each customer can register their own webhook endpoints with isolated delivery tracking
• **Compliance and audit requirements** - Maintain detailed logs of all webhook delivery attempts with timestamps and status codes for regulatory compliance
### How it works
The component uses Convex's component architecture to provide a `WebhookSender` class that manages destinations and queued deliveries. You register webhook URLs with `registerDestination()` which returns a signing secret, then send webhooks using the `send()` method with a destination ID, event type, and payload.
Webhooks are delivered as HTTP POST requests with Standard Webhooks-compatible headers including `webhook-signature` for HMAC-SHA256 verification. The component handles automatic retries with configurable exponential backoff windows and supports both parallel and serialized delivery modes per destination.
Delivery tracking is built-in through methods like `getWebhookStatus()` and `getDeliveryHistory()` which provide full audit trails of delivery attempts. The component also includes a `verifyWebhookSignature()` utility function for webhook recipients to validate incoming signatures using the `whsec_` prefixed secrets.
### Upstream README
# convex-webhook-sender
Managed webhook delivery for Convex
HMAC signing • Automatic retries • Exponential backoff • Delivery tracking
[View Demo](#-live-demo) • [Documentation](#-setup) • [API Reference](#-api-reference)
---
A Convex component for managed outbound webhook delivery with HMAC signing, retries, exponential backoff, and delivery tracking.
## Features
- **HMAC-SHA256 signing** with `whsec_` prefixed secrets (Standard Webhooks compatible)
- **Automatic retries** with exponential backoff (configurable max retries & window)
- **Delivery modes**: parallel (default) or serialized (FIFO per destination)
- **Delivery tracking**: full attempt history with status codes and errors
- **Signature verification utility** for webhook recipients
## Installation
```bash
npm install convex-webhook-sender
```
## Setup
In your `convex/convex.config.ts`:
```typescript
import { defineApp } from "convex/server";
import webhookSender from "convex-webhook-sender/convex.config";
const app = defineApp();
app.use(webhookSender);
export default app;
```
Create the client in a helper file like `convex/webhooks.ts`:
```typescript
import { WebhookSender } from "convex-webhook-sender";
import { components } from "./_generated/api";
export const webhooks = new WebhookSender(components.webhookSender);
```
## Usage
### Register a destination
```typescript
// convex/myFunctions.ts
import { mutation } from "./_generated/server";
import { webhooks } from "./webhooks";
export const addWebhookEndpoint = mutation({
args: { url: v.string() },
handler: async (ctx, args) => {
const { destinationId, secret } = await webhooks.registerDestination(ctx, {
url: args.url,
maxRetries: 5,
retryWindowMs: 24 * 60 * 60 * 1000, // 24 hours
});
// Share `secret` with the recipient for signature verification
return { destinationId, secret };
},
});
```
### Send a webhook
```typescript
export const onOrderCreated = mutation({
handler: async (ctx) => {
await webhooks.send(ctx, {
destinationId: "...",
eventType: "order.created",
payload: { orderId: "123", total: 99.99 },
});
},
});
```
### Query delivery status
```typescript
export const checkWebhook = query({
args: { webhookId: v.string() },
handler: async (ctx, args) => {
return await webhooks.getWebhookStatus(ctx, args.webhookId);
},
});
```
### Verify signatures (recipient side)
```typescript
import { verifyWebhookSignature } from "convex-webhook-sender";
// In your webhook handler (e.g., Express, Next.js API route)
const isValid = await verifyWebhookSignature(
rawBody,
{
"webhook-id": req.headers["webhook-id"],
"webhook-timestamp": req.headers["webhook-timestamp"],
"webhook-signature": req.headers["webhook-signature"],
},
"whsec_your_secret_here"
);
```
## API
### `WebhookSender` class
| Method | Description |
|--------|-------------|
| `registerDestination(ctx, config)` | Register a new webhook URL. Returns `{ destinationId, secret }` |
| `removeDestination(ctx, id)` | Deactivate a destination |
| `updateDestination(ctx, id, updates)` | Update destination config |
| `send(ctx, { destinationId, eventType, payload })` | Queue a webhook for delivery |
| `getDestination(ctx, id)` | Get destination details |
| `listDestinations(ctx, options?)` | List all destinations |
| `getSigningSecret(ctx, id)` | Get the HMAC signing secret |
| `getWebhookStatus(ctx, id)` | Get webhook delivery status |
| `getDeliveryHistory(ctx, destId, options?)` | Get delivery attempt history |
| `getFailedWebhooks(ctx, destId, options?)` | Get failed webhooks |
### Webhook payload format
Webhooks are delivered as HTTP POST with:
```
POST
Content-Type: application/json
webhook-id: msg_
webhook-timestamp:
webhook-signature: v1,
{"type":"","timestamp":,"data":}
```
### Signature verification
The signature is computed as: `HMAC-SHA256(secret, "msg_id.timestamp.body")`
## 🚀 Live Demo
[**View the live demo →** Click here to see the webhook sender in action](https://webhook-sender-demo.vercel.app)
## License
MIT
---