- Published on
Webhook & Event Delivery Infrastructure in 2026 — Svix / Hookdeck / ngrok / Sequin / Convoy / Standard Webhooks Deep Dive
- Authors

- Name
- Youngju Kim
- @fjvbn20031
"Webhooks are the simplest async integration pattern, and also the one that breaks most often. In 2026, there is no good reason left to implement raw POST handlers yourself." — Standard Webhooks Working Group, 2024
Webhooks have barely changed since Jeff Lindsay coined the term in 2007, but their operational surface area has exploded. Integrating one SaaS — Stripe, Twilio, Shopify, GitHub, Slack — now means absorbing hundreds of thousands to millions of POSTs a day, and shipping outbound events from your own service has grown to the same scale.
As of May 2026, "webhook infrastructure" no longer means "an HTTP POST handler". It splits into five distinct categories: Gateway, Reliability, Tunnel, Debugger, and Cloud-native Event Bus. This post walks through Svix, Hookdeck, ngrok, smee.io, Sequin, Convoy, Webhook.site, RequestBin, Beeceptor, AWS EventBridge, GCP Eventarc, Azure Event Grid, Inngest, and the Standard Webhooks specification — all in one place.
1. The 2026 Webhook Map — Gateway / Reliability / Tunnel / Cloud-Native
A useful first cut is by role.
| Category | Representative products | Role |
|---|---|---|
| Gateway (outbound) | Svix, Hookdeck Connect, Convoy, AWS EventBridge Pipes | When you emit events to your customers — queue, retry, signing, dashboard |
| Reliability (inbound) | Hookdeck, Inngest, Convoy, Tinybird Events | Queue, filter, retry, transform webhooks arriving from external SaaS |
| Tunnel (dev) | ngrok, Cloudflare Tunnel, Tailscale Funnel, smee.io | Expose local machines to the internet for dev/test |
| Debugger | Webhook.site, RequestBin, Beeceptor, Diagnostic | Give you a URL and visualize whatever arrives |
| Cloud-native event bus | AWS EventBridge, GCP Eventarc, Azure Event Grid | Route events inside and across cloud services and SaaS partners |
Producer and consumer sides have very different requirements. Producers care about "did my event reach the customer, and if not, how many times did we retry?" Consumers care about "can I buffer this random external traffic away from my core systems?" Hookdeck handles both ends; Svix is producer-centric.
The first decision in webhook infrastructure is always "am I the sender, the receiver, or both?". That question runs through this entire post.
2. The Webhook Standard — Standard Webhooks (April 2023) and Its Impact
Twenty years of unstandardized growth left every SaaS with its own signing header, payload format and retry policy. Stripe uses Stripe-Signature, GitHub uses X-Hub-Signature-256, Shopify uses X-Shopify-Hmac-Sha256, Slack uses X-Slack-Signature — each integration meant learning another SDK.
In April 2023, Svix-led and co-signed by Zapier, Twilio, Lob, Ngrok, Vercel and Supabase, the Standard Webhooks initiative launched to normalize the chaos. The core agreements:
- Three common headers:
webhook-id,webhook-timestamp,webhook-signature - Signature: HMAC-SHA256, base64-encoded,
v1,prefix - Timestamp validation: default 5-minute tolerance window (replay protection)
- Payload format: JSON, recommended
type+dataenvelope - Retry policy recommendation: exponential backoff at 5s, 5m, 30m, 2h, 5h, 10h, 16h — give up after roughly 24h
- Event ID: a stable id usable as the consumer's idempotency key
By 2024, modern SaaS like Vercel, Supabase, Resend, Linear and Cal.com shipped Standard-Webhooks-compatible from day one. In 2025 Stripe partially adopted it in their v2 Event API. By May 2026, more than 100 SaaS support the standard headers (webhook-id, webhook-timestamp, webhook-signature).
The biggest payoff is a single verification SDK: the standardwebhooks package can verify signatures for every compliant SaaS, so you stop relearning a new client per integration.
3. Signature Verification — HMAC-SHA256, Timing-Safe Compare
The core of webhook security is proving the request actually came from the SaaS that claims to have sent it. Almost everyone uses HMAC-SHA256. The canonical flow:
- SaaS and your service share a secret (
signing secret) - SaaS HMAC-SHA256s a string built from payload + timestamp
- Sends the signature in a header
- You recompute it with the same key
- Always use a timing-safe compare (timing-attack protection)
A from-scratch Node.js verifier compatible with Standard Webhooks:
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verifyStandardWebhook(opts: {
payload: string // raw body — byte-exact original, NOT JSON.stringify of a parsed object
headers: Record<string, string>
secret: string // 'whsec_xxx' base64-encoded key
toleranceSeconds?: number
}): boolean {
const { payload, headers, secret, toleranceSeconds = 300 } = opts
const id = headers['webhook-id']
const timestamp = headers['webhook-timestamp']
const signature = headers['webhook-signature']
if (!id || !timestamp || !signature) return false
// 1) Timestamp window check (replay protection)
const ts = parseInt(timestamp, 10)
const now = Math.floor(Date.now() / 1000)
if (Math.abs(now - ts) > toleranceSeconds) return false
// 2) Assemble signed content: "id.timestamp.payload"
const signedContent = `${id}.${timestamp}.${payload}`
// 3) Decode base64 secret into raw bytes
const secretBytes = Buffer.from(secret.replace(/^whsec_/, ''), 'base64')
// 4) Compute HMAC-SHA256
const expected = createHmac('sha256', secretBytes)
.update(signedContent)
.digest('base64')
// 5) Header may contain multiple "v1,sigN" entries (key rotation)
const sigs = signature.split(' ').map((s) => s.split(',')[1]).filter(Boolean)
// 6) Timing-safe compare — NEVER use ===
return sigs.some((sig) => {
const sigBytes = Buffer.from(sig, 'base64')
const expBytes = Buffer.from(expected, 'base64')
if (sigBytes.length !== expBytes.length) return false
return timingSafeEqual(sigBytes, expBytes)
})
}
Three traps to avoid.
Receive the raw bytes. If Express body-parser or a Next.js Route Handler auto-parses JSON and you then JSON.stringify it, whitespace and key order will diverge and the signature will fail. In Next.js App Router use await req.text(); in Express use bodyParser.raw({ type: '*/*' }).
Don't skip the timestamp check. Verifying the signature alone lets an attacker who captures one valid request replay it forever. Standard Webhooks, Stripe and Slack all default to a 5-minute window.
Always use a constant-time compare. === and Buffer.compare short-circuit on the first differing byte, leaking the signature byte-by-byte through timing differences. Node.js has crypto.timingSafeEqual, Python has hmac.compare_digest, Go has subtle.ConstantTimeCompare.
4. Idempotency + Retries + Exponential Backoff
The second hard problem is "what happens when the receiver gets the same event twice?". Senders retry until they see a 200, so a timeout or a brief outage means duplicate deliveries.
The canonical idempotency pattern is a dedup table keyed by event id.
// Idempotent handler — Postgres + Redis combo
import { db } from '@/lib/db'
import { redis } from '@/lib/redis'
export async function handleWebhookIdempotent(event: {
id: string // SaaS-provided unique id (webhook-id header or payload id)
type: string
data: unknown
}) {
// 1) Fast Redis lock (TTL 60s) — guard against concurrent deliveries
const lockKey = `webhook:lock:${event.id}`
const acquired = await redis.set(lockKey, '1', 'NX', 'EX', 60)
if (!acquired) {
// Another worker is processing — 200 so the SaaS clears its retry queue
return { status: 'in-flight' }
}
try {
// 2) Postgres durable record (UNIQUE constraint = dedup)
const inserted = await db.query(
`INSERT INTO processed_webhooks (event_id, event_type, received_at)
VALUES ($1, $2, NOW())
ON CONFLICT (event_id) DO NOTHING
RETURNING event_id`,
[event.id, event.type]
)
if (inserted.rowCount === 0) {
// Already processed — 200
return { status: 'duplicate' }
}
// 3) Real business logic
await processBusinessLogic(event)
return { status: 'processed' }
} finally {
await redis.del(lockKey)
}
}
For senders, exponential backoff with jitter is the standard. The Standard Webhooks recommendation:
| Attempt | Wait | Cumulative |
|---|---|---|
| 1 | immediate | 0s |
| 2 | 5s | 5s |
| 3 | 5m | 5m 5s |
| 4 | 30m | 35m |
| 5 | 2h | 2h 35m |
| 6 | 5h | 7h 35m |
| 7 | 10h | 17h 35m |
| 8 | 16h | ~33h → give up |
Add jitter of plus or minus 10–25 percent to prevent thundering herds.
A receiver can signal "not now" in two ways. 429 Too Many Requests with a Retry-After header is honored by good senders. 5xx enters the standard backoff queue. 4xx (400, 401, 422) is treated as permanent failure and not retried — never return 4xx for transient problems.
5. Svix — The Open-Source Webhook Gateway
Svix (svix.com) founded in 2021, Series A in 2023, runs the best-known open-source webhook gateway. Lob, Brex, Clerk, Lightspeed, Benchling and Resend run their webhooks on Svix.
The pitch: "build Stripe-grade webhooks in a day, not a quarter." The stuff you'd have to build yourself — queue, retries, exponential backoff, signing, idempotency, circuit breakers, dashboard, log retention, replay UI, OpenAPI schema — is replaced by an SDK call.
// Sending an event to a customer with Svix
import { Svix } from 'svix'
const svix = new Svix(process.env.SVIX_AUTH_TOKEN!)
// 1) Create the customer application once
const app = await svix.application.create({
name: 'Acme Corp',
uid: 'cust_acme_001',
})
// 2) The customer registers an endpoint (dashboard or API)
await svix.endpoint.create(app.id, {
url: 'https://acme.com/webhooks',
description: 'Production endpoint',
})
// 3) Send an event — Svix handles queue, retries, signing
await svix.message.create(app.id, {
eventType: 'invoice.paid',
eventId: `evt_${invoice.id}`, // idempotency key
payload: {
invoice_id: invoice.id,
amount: invoice.amount,
customer: invoice.customer_id,
},
})
The open-source version (github.com/svix/svix-webhooks) is a Rust server on top of PostgreSQL, Redis and RabbitMQ that you can self-host. The cloud version is free up to 5,000 messages a month, then per-message billed.
In November 2025 Svix shipped an embedded dashboard widget for React and Vue (@svix/react), letting your customers register, test and inspect their own endpoints inside your app. That's the most time-consuming piece to build from scratch and a real differentiator.
6. Hookdeck — The Webhook Reliability Platform
Hookdeck (hookdeck.com), based in Montreal, was founded in 2021 and raised a Series A in 2024. If Svix is sender-centric, Hookdeck is receiver-and-bidirectional-centric.
The core scenario is inbound webhook reliability. Register https://hkdk.events/xxx as the webhook URL with Stripe, Shopify or GitHub. Hookdeck receives, buffers, retries and forwards to your backend. When your backend is down Hookdeck holds the queue, and you can replay failed events from the dashboard in one click.
# Hookdeck CLI — forward inbound webhooks to a local dev server
hookdeck listen 3000 stripe --path /api/webhooks/stripe
# Sample output:
# Inbound URL: https://hkdk.events/abcd1234
# Forwarding to: http://localhost:3000/api/webhooks/stripe
# Connection: stripe-local
One command and you have an inbound URL without ngrok, plus every request logged in the Hookdeck dashboard. The same command can target a production URL, so you can use one gateway across local, staging and prod.
Hookdeck Connect, launched in 2025, is the outbound counterpart that competes head-on with Svix and shares the dashboard with the inbound side.
A real Hookdeck differentiator is Filtering and Transformation: arbitrary JavaScript can rewrite incoming payloads or filter on event type before forwarding to your backend.
// Hookdeck Transformation example
addHandler('transform', (request, context) => {
// Pass only Stripe charge.succeeded
if (request.body.type !== 'charge.succeeded') {
return null // drop
}
// Flatten payload
return {
...request,
body: {
charge_id: request.body.data.object.id,
amount: request.body.data.object.amount,
customer: request.body.data.object.customer,
},
}
})
7. ngrok / Cloudflare Tunnel — Local Tunneling
The eternal dev problem is "how do I get external traffic to my laptop?". ngrok (ngrok.com) has been the de facto answer since 2013.
In 2024 ngrok rebranded as Ngrok Edge, evolving from "just tunnels" into a full ingress platform with API Gateway, OAuth, mutual TLS and rate limiting.
# Basic — expose local port 3000 to the internet
ngrok http 3000
# Reserved domain (paid plan)
ngrok http 3000 --domain=acme-dev.ngrok.app
# Use as an auth gateway
ngrok http 3000 \
--domain=api-dev.acme.dev \
--oauth=google \
--oauth-allow-domain=acme.com
# YAML config
# ~/.ngrok2/ngrok.yml
# tunnels:
# webhook-dev:
# proto: http
# addr: 3000
# domain: webhooks-dev.acme.dev
# request_header_add:
# - "X-Forwarded-Source: ngrok-dev"
The most popular ngrok alternative is Cloudflare Tunnel (formerly Argo Tunnel). With a Cloudflare account you get a permanent free domain, and traffic flows through Cloudflare's global network with DDoS and WAF applied automatically.
# Install cloudflared and log in once
cloudflared tunnel login
# Create a tunnel
cloudflared tunnel create my-dev-tunnel
# DNS route (your domain must be on Cloudflare DNS)
cloudflared tunnel route dns my-dev-tunnel webhook-dev.acme.com
# Forward to a local service
cloudflared tunnel run --url http://localhost:3000 my-dev-tunnel
Tailscale Funnel, GA in 2023, exposes a node from your existing Tailnet to the public internet. If your team already runs Tailscale it's the lowest-friction option, no extra account required.
Decision matrix: quick one-off is ngrok free tier; shared permanent dev URL is Cloudflare Tunnel (free); enterprise OAuth/mTLS is paid Ngrok Edge; team already on Tailscale is Funnel.
8. smee.io (GitHub) — Free Dev Forwarding
smee.io (smee.io), run by GitHub, is even simpler than ngrok. Click "Start a new channel" once and you get a permanent URL; the CLI streams incoming requests over Server-Sent Events to your local server.
# Install the CLI
npm install -g smee-client
# Forward
smee --url https://smee.io/abcd1234 --path /webhooks/github --port 3000
# Or from code:
# import SmeeClient from 'smee-client'
# const smee = new SmeeClient({
# source: 'https://smee.io/abcd1234',
# target: 'http://localhost:3000/webhooks/github',
# logger: console,
# })
# smee.start()
smee's strengths are free, unlimited, no signup. The weaknesses are no SLA, GitHub may rate-limit a flood, and there is no auth or filtering. Because it shows up in GitHub's official GitHub Apps docs, it's the lowest-friction choice for learning GitHub webhooks.
In 2025 smee.io added a browser payload preview, so opening the channel URL gives you a live JSON view of incoming requests.
9. Sequin — Postgres to Webhooks/Kafka
Sequin (sequin.io) founded in 2022, Series A from Andreessen Horowitz in 2024. Its angle is streaming Postgres changes to webhooks, Kafka or SQS. It's a CDC (Change Data Capture) tool that treats webhooks as a first-class destination.
A typical scenario: you don't have time to add integration code to your backend, so Sequin reads your Postgres write-ahead log (WAL) and emits the INSERT/UPDATE/DELETE events to an external HTTP endpoint for you.
# sequin.yaml — Postgres table -> webhook
sources:
- name: orders-pg
type: postgres
url: postgresql://user:pass@db.acme.com:5432/app
publication: sequin_pub
slot: sequin_slot
destinations:
- name: warehouse-webhook
type: webhook
url: https://warehouse.acme.com/api/orders
headers:
authorization: Bearer ${WAREHOUSE_TOKEN}
retry:
max_attempts: 8
backoff: exponential
streams:
- name: orders-to-warehouse
source: orders-pg
destination: warehouse-webhook
tables:
- name: orders
actions: [insert, update]
filter: "status IN ('paid', 'shipped')"
The upside is zero application code change: DB changes propagate to the outside world without touching your services. The downside is that Postgres WAL has sharp edges — slot management during schema changes needs care. As of 2025 Sequin also ships built-in SaaS integrations like Stripe, Linear and Notion, so two-way syncs like "new Stripe customer -> INSERT into our DB" are first-class.
Neighbors include Debezium (open source, JVM-based), Fivetran HVR and Airbyte, but Sequin has the cleanest first-class support for webhook destinations.
10. Convoy — Open-Source Delivery
Convoy (getconvoy.io, github.com/frain-dev/convoy), based in Lagos, is an open-source webhook gateway written in Go and MIT-licensed. It's the self-hosted competitor to Svix Cloud.
# Docker Compose to spin up Convoy
git clone https://github.com/frain-dev/convoy
cd convoy
docker compose -f deploy/docker-compose.yml up -d
# Dashboard on 5005, API on 5004 by default
open http://localhost:5005
Convoy's data model mirrors Svix: Project, Endpoint, Event and Subscription. Push events via REST API, Convoy puts them in a Redis-backed queue, workers deliver to the external endpoint.
# Send an event via the API
curl -X POST http://localhost:5004/api/v1/projects/{project_id}/events \
-H "Authorization: Bearer CONVOY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endpoint_id": "endpoint_abc",
"event_type": "user.created",
"data": {
"user_id": "u_123",
"email": "alice@example.com"
}
}'
Convoy's signature feature is filter expressions — a SQL-like syntax that lets each subscription opt into specific event shapes, e.g. data.amount > 1000 AND data.currency == 'USD'.
Convoy Cloud also exists if you don't want to host, but its market share is small compared to Svix and Hookdeck. It's a serious option in environments where self-hosting is mandatory: regulated finance, healthcare, GovCloud.
11. Webhook.site / RequestBin / Beeceptor — Debugging Tools
The first thing you need when integrating any webhook is "what does this thing actually send me?". You need to see the payload shape, header names, encoding, with your own eyes.
Webhook.site (webhook.site) is the most popular free option. Opening the page gives you an instant unique URL; every request to it appears in real time with payload, headers, query, method and response time on one screen. The free tier allows 100 requests a day; Premium gives unlimited, permanent retention, custom responses and JavaScript-controlled responses.
# Quick test
curl -X POST https://webhook.site/abcd1234 \
-H "Content-Type: application/json" \
-d '{"hello": "world"}'
# Open https://webhook.site/#!/abcd1234 in a browser to watch live
RequestBin (requestbin.com) was acquired by Pipedream and went paid, but the open-source version (github.com/Runscope/requestbin) is self-hostable.
Beeceptor (beeceptor.com) goes beyond inspection into mock API server territory. You define conditional responses to incoming requests, so you can fake an external API in five minutes — perfect for simulating a downed SaaS in integration tests.
// Beeceptor response rule (JS expression)
// Condition: request.body.action === "create"
// Response: 201 + JSON
{
"id": "{{$randomUUID}}",
"created_at": "{{$timestamp}}",
"echo": "{{request.body}}"
}
Diagnostic (diagnostic.dev), launched in 2024, is the newest of the bunch. Instead of just being an inbox, it infers payload schemas per SaaS and emits an OpenAPI spec. After a few days of receiving real payloads, it tells you things like "this SaaS's invoice.paid event averages 12 fields, three of which are optional."
Picking between them is straightforward. Quick one-off debug: Webhook.site. Mock API: Beeceptor. Long-term payload analysis: Diagnostic.
12. AWS EventBridge / Google Eventarc / Azure Event Grid — Cloud-Native
Cloud providers ship their own event routers, going beyond webhooks into inter-service event bus territory.
AWS EventBridge, GA in 2019, routes both AWS-internal events (S3 PUT, EC2 state change, etc.) and 100+ external SaaS partners (Stripe, Datadog, Shopify, GitHub) in one place.
# EventBridge rule — Stripe payment success triggers Lambda
aws events put-rule \
--name stripe-payment-success \
--event-pattern '{
"source": ["aws.partner/stripe.com"],
"detail-type": ["charge.succeeded"]
}'
aws events put-targets \
--rule stripe-payment-success \
--targets 'Id=1,Arn=arn:aws:lambda:us-east-1:123:function:processPayment'
The killer features are EventBridge Pipes (GA 2022) and the Schema Registry. Pipes is a GUI source-filter-enrich-target pipeline; Schema Registry auto-registers and versions incoming event schemas.
Google Eventarc is the GCP version. It triggers Cloud Run, Cloud Functions or Workflows from 70+ Google Cloud services (GCS, BigQuery, Pub/Sub, Cloud Build, etc.). External SaaS coverage is narrower than EventBridge, but it has first-class CloudEvents v1.0 support.
# Eventarc trigger — Cloud Run on GCS object create
gcloud eventarc triggers create gcs-upload-trigger \
--location=us-central1 \
--destination-run-service=process-upload \
--destination-run-region=us-central1 \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=acme-uploads" \
--service-account=eventarc@my-project.iam.gserviceaccount.com
Azure Event Grid is Microsoft's offering. It routes Azure service events (Blob Storage, IoT Hub, Service Bus, etc.) plus SaaS, and bundles an MQTT v5 broker, making it especially strong for IoT. Event Grid Namespaces (GA 2024) combine pub/sub and webhook delivery in a single resource.
Choosing the cloud-native bus mostly reduces to which cloud are you already on. AWS -> EventBridge, GCP -> Eventarc, Azure -> Event Grid. For multi-cloud, a cloud-neutral SaaS like Hookdeck or Svix is the saner choice.
13. Inngest's Webhook Integration
Inngest (inngest.com), founded in 2022, raised a Series B in 2024. Its pitch is "queues, crons, workflows and webhooks in one SDK."
Inngest started as its own event system, but in 2024 Webhook Source became a first-class citizen. Register a Stripe, GitHub or Shopify URL in the Inngest dashboard, Inngest becomes the inbox and auto-translates inbound events into Inngest events.
// Inngest function reacting to a Stripe webhook
import { inngest } from '@/inngest/client'
export const handleStripePayment = inngest.createFunction(
{
id: 'handle-stripe-payment',
retries: 5,
idempotency: 'event.data.id', // Stripe event id -> idempotent
},
{ event: 'stripe/charge.succeeded' }, // Inngest auto-routes
async ({ event, step }) => {
// step.run wraps with auto-retry + memoized result
const customer = await step.run('fetch-customer', async () =>
db.customer.findUnique({ where: { stripeId: event.data.customer } })
)
await step.run('send-receipt', async () =>
mailer.sendReceipt(customer.email, event.data)
)
// step.sleep suspends the function at zero cost
await step.sleep('wait-1h', '1h')
await step.run('send-followup', async () =>
mailer.sendFollowup(customer.email)
)
}
)
Inngest's appeal is consolidating webhooks + queues + workflows + crons into one SDK. Where Hookdeck stops at the reliability layer, Inngest layers business-logic orchestration on top.
Neighbors include Trigger.dev, Defer and Temporal Cloud; the cloud-native counterpart is AWS Step Functions + EventBridge.
14. Field Reports — Toss (Korea), Mercari and SmartHR (Japan)
Korea — Toss: Toss Payments offers merchants payment-approval/cancellation/refund webhooks and runs a fully in-house gateway. According to a 2025 Toss Payments engineering post, they handle hundreds of millions of webhooks per day on a Kafka-backed queue, a worker pool, a Redis-based idempotency cache and MongoDB for long-term logs. Signatures are double-layered RSA-SHA256 (public-key verifiable) plus HMAC, and merchants can replay failed events directly from a dashboard.
What's special about Toss is regulated-finance logging. Every webhook send and receive must be retained for five years, and external auditors expect "given a transaction id, find payload + signature + retry history in under a second". That's the kind of requirement that's hard to outsource to Svix or Hookdeck, and it's the reason Toss built their own.
Japan — Mercari: Mercari wires inter-microservice async integration on Cloud Pub/Sub + Cloud Run + Eventarc. Per a 2024 Mercari engineering post, payment, inventory and shipping domains emit and consume events exclusively through Pub/Sub topics. External SaaS integrations (SendGrid, Stripe Connect, etc.) come in via Eventarc triggers. The invariant is that internal services never receive an external webhook directly — Eventarc and Pub/Sub always sit in front.
Japan — SmartHR: HR SaaS SmartHR exposes employee-record-change webhooks to its customer HR teams. The 2025 SmartHR Tech Blog architecture is Rails + Sidekiq, retries via Sidekiq's exponential backoff (up to 25 attempts, ~21 days), signing with HMAC-SHA256 and a proprietary payload schema. The standout feature is a per-endpoint Health Score: low-scoring endpoints get circuit-broken automatically and the customer gets an email alert.
The common thread across all three is build-it-yourself plus operational automation. Past a certain scale, the cost of a managed gateway exceeds the cost of building one. But "yourself" means 6 to 12 engineer-months, so SaaS pre-Series-A almost always start on Svix or Hookdeck and only migrate after PMF.
15. References
- Standard Webhooks specification —
https://www.standardwebhooks.com/ - Standard Webhooks GitHub —
https://github.com/standard-webhooks/standard-webhooks - Svix documentation —
https://docs.svix.com/ - Svix open source —
https://github.com/svix/svix-webhooks - Hookdeck documentation —
https://hookdeck.com/docs - Hookdeck CLI —
https://github.com/hookdeck/hookdeck-cli - Convoy open source —
https://github.com/frain-dev/convoy - Convoy documentation —
https://docs.getconvoy.io/ - ngrok documentation —
https://ngrok.com/docs - Cloudflare Tunnel —
https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/ - Tailscale Funnel —
https://tailscale.com/kb/1223/funnel - smee.io —
https://smee.io/ - Sequin —
https://sequin.io/ - Webhook.site —
https://webhook.site/ - Beeceptor —
https://beeceptor.com/ - RequestBin (Pipedream) —
https://pipedream.com/requestbin - AWS EventBridge —
https://docs.aws.amazon.com/eventbridge/ - AWS EventBridge Pipes —
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html - Google Eventarc —
https://cloud.google.com/eventarc/docs - Azure Event Grid —
https://learn.microsoft.com/en-us/azure/event-grid/ - Inngest webhooks —
https://www.inngest.com/docs/platform/webhooks - Stripe webhook signatures —
https://docs.stripe.com/webhooks/signatures - GitHub webhook deliveries —
https://docs.github.com/en/webhooks - Slack request signing —
https://api.slack.com/authentication/verifying-requests-from-slack - Toss Payments developer center —
https://docs.tosspayments.com/ - Mercari Engineering Blog —
https://engineering.mercari.com/en/blog/ - SmartHR Tech Blog —
https://tech.smarthr.jp/ - CloudEvents specification —
https://cloudevents.io/ - OWASP Webhook Security Cheat Sheet —
https://cheatsheetseries.owasp.org/cheatsheets/Webhook_Security_Cheat_Sheet.html