VectorLive demo, free and Pro.
The first three sections run the real @sweberdev/vector build in your browser: signing and verification, the sender with its retry schedule and delivery log, and the SSRF guard. The receivers in the delivery simulator are simulated, nothing is sent over the network.
Nothing you type leaves your browser. Secrets are generated with Web Crypto on this page and are gone when you reload it.
Sign and verify
Three headers, one HMACStandard Webhooks, Svix compatible.
Vector signs the message id, the timestamp and the body with HMAC-SHA256 and sends the result in webhook-id, webhook-timestamp and webhook-signature. Any Standard Webhooks or Svix library can verify it. Change the body, the secret or the clock on the receiving side and watch verification fail with the error code your handler would see.
Loading Vector…
Delivery simulator
Retries you can watchReal sender, simulated receivers, fake clock.
This is createVector with a memory store, three endpoints of the tenant acme and a fetch that answers the way you set each receiver. The clock only moves when you move it, and after every step the worker runs one process() pass, so you can follow each attempt, the backoff and the automatic disabling of a dead endpoint.
Loading Vector…
SSRF guard
Customer URLs never reach your networkChecked on create and before every attempt.
Endpoint URLs come from your customers. Vector refuses localhost, private and link-local networks (including the cloud metadata address 169.254.169.254), plain http and credentials in the URL, unless you allow them. On Node.js it also resolves the host name and checks every address, so a DNS record pointing inside your network is caught too.
Loading Vector…
Browsers have no DNS lookup, so in this demo host names are resolved from a small table: intranet.acme.example points to 10.0.0.12, every other name to a public address.
Examples
Pro
The portal, the catalog and the night shiftVector Pro.
The free package sends, retries and logs. Vector Pro adds the parts you would otherwise build next: an embeddable portal where your customers manage their own endpoints, a typed event catalog that validates payloads and generates docs, and operations tooling for alerts, recovery after outages, metrics and retention. Vector Pro is not on sale yet; the snippets show how it plugs in.
Customer portal: one route handler, scoped to the tenant
// app/api/webhooks/[...path]/route.ts
import { createPortalHandler } from "@weber-development/vector-portal"
import { vector } from "@/lib/vector"
import { getSession } from "@/lib/auth"
const handler = createPortalHandler(vector, {
basePath: "/api/webhooks",
// Every route is scoped to the tenant you return here.
authorize: async (request) => {
const session = await getSession(request)
return session ? { tenant: session.organisationId } : null
},
eventTypes: [
{ type: "invoice.paid", description: "An invoice was paid in full." },
{ type: "customer.updated", description: "Customer details changed." },
],
})
export { handler as GET, handler as POST, handler as PATCH, handler as DELETE }And the React components on your settings page
// app/settings/webhooks/page.tsx
"use client"
import { WebhookPortal } from "@weber-development/vector-portal/react"
import "@weber-development/vector-portal/styles.css"
export default function WebhooksSettings() {
return <WebhookPortal apiBase="/api/webhooks" />
}The handler serves endpoints, secrets, the message log, retries and test events for exactly one tenant, the one your authorize function returns. The components talk to it and bring their own styles.
Event catalog
import { z } from "zod"
import { defineCatalog } from "@weber-development/vector-catalog"
export const catalog = defineCatalog({
"invoice.paid": {
description: "An invoice was paid in full.",
schema: z.object({ invoiceId: z.string(), amount: z.number().int() }),
example: { invoiceId: "inv_123", amount: 4200 },
},
})
// Typed and validated before Vector stores the message
await catalog.send(vector, "invoice.paid", { invoiceId: "inv_123", amount: 4200 }, { tenant: "acme" })
// Docs for your customers
catalog.toMarkdown()
catalog.toAsyncAPI({ title: "Acme webhooks", version: "1.0.0" })
catalog.toTypeScript()Every event type gets a schema (Zod, Valibot, ArkType or any Standard Schema library). Payloads are checked before they are sent, and the same catalog generates Markdown docs, an AsyncAPI 3 file and TypeScript types for your customers.
vector-ops sends alerts to Slack, email or a webhook when an endpoint keeps failing, replays everything that failed during an outage in one command, writes a health report, exposes Prometheus metrics and deletes old log data on a schedule.
Next
Send your first webhookMIT, free.
Install @sweberdev/vector, create an endpoint for a customer, call send() and start the worker. The getting started guide covers PostgreSQL, serverless and the receiving side.