Reliable webhooks
in a few lines of code
Send events, route to subscribers, retry on failure. Production-grade infrastructure. No servers to manage.
SDKs in 8 languages CLI for your terminal MCP server for AI agents
See pricingimport { NahookClient } from "@nahook/client";
const nahook = new NahookClient("nhk_us_...");
// Send directly to an endpoint
await nahook.send("ep_abc123", {
payload: { orderId: "ord_123", status: "paid" },}
);
// Fan-out to all subscribers
await nahook.trigger("order.paid", {
payload: { orderId: "ord_123" },}
);How it works
Push a payload to a specific endpoint. We deliver it — with retries, idempotency, and full visibility.
Hover or tap to pause · Auto-loops · Reduced motion respected
Or fan out to many endpoints
One event in, delivered to every subscriber — retried, observed, never lost.
Hover or tap to pause · Auto-loops · Reduced motion respected
Everything you need for webhooks
Built for developers. Designed for scale. No infrastructure to manage.
Signed deliveries by default
Every webhook signed with HMAC-SHA256 following the Standard Webhooks spec. Your receiver verifies with any library in any language — knowing the payload hasn't been tampered with, and that it actually came from your workspace.
# Incoming POST request headers (Standard Webhooks spec)
webhook-id: msg_del_x4k2
webhook-timestamp: 1717589412
webhook-signature: v1,mZqGc...
Content-Type: application/json
// Verify in any language
const ok = nahook.verify(req)
// ✓ signature valid (HMAC-SHA256) # Producer fires one event
$ nahook trigger order.paid \
--data '{"orderId":"ord_123"}'
✓ fan-out to 3 endpoints
# Inspect the resulting deliveries
$ nahook events list --status delivered --limit 3
del_x4k2 order.paid ep_inventory 47ms
del_a91j order.paid ep_email 62ms
del_p3qn order.paid ep_analytics 38ms
# Add ep_audit in the dashboard next month?
# This trigger() call never changes. Fan-out to every subscriber
Define event types in your workspace and subscribe endpoints to them in the dashboard. Fire one event in your code — Nahook delivers to every matching subscriber with its own retry policy and signing key. Add a new consumer later, and the same trigger() call starts reaching it. No producer change.
Safe retries with idempotency keys
Pass --idempotency-key on any send and Nahook dedupes for 15 minutes. Network blip? Retry from your scripts, your job runner, or your CI — the same key returns the same delivery, no duplicate webhook fires downstream. Standard Idempotency-Key header semantics, no proprietary syntax.
# First send — accepted, delivery enqueued
$ nahook send ep_acme \
--data '{"orderId":"ord_123"}' \
--idempotency-key order_123_paid
✓ accepted del_x4k2 (47ms)
# Network blip? Retry safely with the same key.
$ nahook send ep_acme \
--data '{"orderId":"ord_123"}' \
--idempotency-key order_123_paid
✓ accepted del_x4k2 (cached — no duplicate fired) And also
Real-time visibility into every delivery
Track success rates, latency percentiles, and endpoint health — all from a single dashboard.
| Endpoint | Delivered | Success |
|---|---|---|
| ep_payments_webhook | 4,821 | 99.9% |
| ep_order_notifications | 3,156 | 99.8% |
| ep_inventory_sync | 2,412 | 98.2% |
Your language. Your framework.
First-class SDKs for 8 languages. Copy, paste, ship.
import { NahookClient } from "@nahook/client";
const nahook = new NahookClient("nhk_us_...");
// Send directly to an endpoint
const send = await nahook.send("ep_abc123", {
payload: { orderId: "ord_123", status: "paid" },
});
// { deliveryId: __TOK5__, status: __TOK6__ }
// Fan-out to all subscribers of an event type
const fan = await nahook.trigger("order.paid", {
payload: { orderId: "ord_123" },
});
// { deliveryIds: [__TOK9__, __TOK10__], status: __TOK11__ }Simple, transparent pricing
Drag to estimate your usage. We'll find the right plan.