Use code for 20% launch discount. Lifetime licenses include complete source code.Copy code

Migration guide

Move Stripe, Svix, and Zapier webhook pipes onto a router you host

Most webhook SaaS is an HTTPS listener, a JSON rewrite, retries, and a second POST. You can run that on a VPS you already pay for.

Self-hosted webhook routing workspace

Hookdeck, Svix, Zapier catch hooks, and Make scenarios all sit in the path between a vendor and your app. That path holds customer events, signing secrets, and retry state. When the bill is per event, you are renting a reverse proxy. Webhook Router is the same architecture on your host: ingest, verify, transform, fan-out, dead-letter.

Target architecture

  1. 01

    Edge TLS

    Caddy or nginx on the VPS. One hostname, paths per source.

  2. 02

    Verify

    Stripe, HMAC, or shared header. Reject before disk write.

  3. 03

    Transform

    Keep the fields your app needs. Map Discord/Slack text here.

  4. 04

    Fan-out

    N destinations, retries, SQLite history, dead-letter replay.

Config vs proprietary SaaS

ConcernCloud webhook SaaSWebhook Router
Ingest URLVendor hostname (Hookdeck, Svix, Zapier catch hook)Your domain, TLS at Caddy/nginx, path per source
Payload storeVendor inbox for 7–30 days, then gone or extra $SQLite on disk you back up with the rest of the box
TransformsVisual mapper or limited JS in the vendor UIJSONPath / JS transform in the route file you version
RetriesVendor backoff, opaque to your logsExponential backoff + dead-letter table you query
Signing secretsStored in the vendor accountEnv file next to Compose. Never leaves the host
Fan-outOne destination per task, billed per taskN destinations per ingest, same license
Cost after year oneStill monthly, scales with event volumeZero. License is one payment

Docker Compose

Put the data volume on the same disk you already back up. Secrets stay in router.env, not in the image.

services:
  webhook-router:
    image: webhook-router:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8090:8090"
    environment:
      TZ: Europe/Madrid
      NEXUS_TELEMETRY: "off"
      STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET}
      GITHUB_WEBHOOK_SECRET: ${GITHUB_WEBHOOK_SECRET}
    volumes:
      - ./data/webhooks:/var/lib/webhook-router
      - ./routes.json:/app/routes.json:ro
      - ./router.env:/run/secrets/env:ro

routes.json

One source per vendor. Transforms are versioned with the rest of the repo. Destinations can be internal HTTP or a chat webhook.

{
  "sources": [
    {
      "id": "stripe",
      "path": "/hooks/stripe",
      "verify": { "type": "stripe", "secret_env": "STRIPE_WEBHOOK_SECRET" },
      "transform": { "keep": ["id", "type", "data.object"] },
      "destinations": [
        { "url": "https://billing.internal/events", "method": "POST" },
        { "url": "https://discord.com/api/webhooks/xxx", "method": "POST",
          "map": { "content": "Stripe {{type}} {{id}}" } }
      ],
      "retry": { "max": 8, "backoff_ms": 500 }
    },
    {
      "id": "github",
      "path": "/hooks/github",
      "verify": { "type": "hmac-sha256", "header": "X-Hub-Signature-256",
                  "secret_env": "GITHUB_WEBHOOK_SECRET" },
      "destinations": [
        { "url": "http://pipeline:8080/jobs/deploy", "method": "POST" }
      ]
    }
  ]
}

Cutover without dropped events

  1. Inventory every vendor URL and signing secret.
  2. Bring the router up behind TLS. Confirm /health.
  3. Load routes.json. Replay a Stripe test event.
  4. Update vendor endpoints to https://hooks.yourdomain.com/…
  5. Keep the cloud inbox for one interval, then disable it.
# 1. Health check the local ingest
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8090/health

# 2. After DNS + TLS, update Stripe
stripe webhook_endpoints update we_xxx \
  --url https://hooks.yourdomain.com/hooks/stripe

# 3. Replay a stored event to prove the path
curl -sS -X POST http://127.0.0.1:8090/api/replay \
  -H "content-type: application/json" \
  -d '{"source":"stripe","event_id":"evt_test"}'

Related setup page: Self-hosted webhook router.

Webhook Router

Own the ingest path

$94.99one-time

  • Source license for Webhook Router
  • Docker Compose and routes.json examples
  • Stripe, HMAC, and header verification
  • Retries, dead-letter, local history
Buy Webhook Router

Checkout stays on Whop. You get the source after payment.

Questions people ask before they switch

Will Stripe still verify signatures?

Yes. Keep STRIPE_WEBHOOK_SECRET in the env file. The router verifies the header before any transform, then forwards a clean JSON body to your apps.

Can I keep Hookdeck as a fallback during cutover?

Point Stripe at both URLs for one interval, or keep Hookdeck as a secondary destination from the router. Disable the cloud URL after a clean week of local history.

Is this a Zapier replacement?

For receive-transform-forward jobs, yes. If you need a thousand SaaS connectors and a visual builder for non-engineers, keep Zapier. This is for developers who already know the payload.

Where do failed deliveries go?

The dead-letter table on disk. Replay with a POST to /api/dlq/{id}/retry. Nothing sits in a vendor dashboard you cannot query.

Keep reading

Guide

Self-hosted cron alternative

Stop paying a monthly bill to fire HTTP on a timer. NexusCron is a self-hosted cron alternative you deploy with Docker on machines you already own.

Guide

EasyCron and cron-job.org alternative

Compare EasyCron, cron-job.org, and other hosted cron products with NexusCron. Same job, no subscription, logs and secrets stay on your disk.

Guide

Migrate off EasyCron to a self-hosted runner

Step-by-step migration from EasyCron to a self-hosted cron runner. Export jobs, map cron expressions, Docker Compose, HTTP pings, and cutover without downtime.

Guide

Migrate cron jobs off cloud providers to self-hosted

Technical guide for migrating cron jobs off cloud providers to self-hosted NexusCron. Architecture, Docker Compose, job mapping, and cutover without missed pings.

Guide

Replace cloud cron services with self-hosted NexusCron

Architecture, Docker Compose, production env vars, and cutover for replacing hosted cron with NexusCron on a VPS you already run. One lifetime payment.

Guide

Migrate EasyCron jobs to self-hosted NexusCron

Architecture, Docker Compose, and cost math for replacing $20–$50/month hosted cron with NexusCron on a VPS you already run. One lifetime payment.

Guide

Self-hosted webhook router

A self-hosted webhook router that receives, transforms, and forwards events on your infrastructure. One payment. No Zapier tax for simple routing.

Guide

Replace cloud webhook queues with local SQLite routing

Technical architecture for replacing cloud webhook queues with local SQLite routing. Production Docker Compose, under 50MB RAM, WAL mode, retries, and dead-letter replay.

Guide

Self-hosted pipeline setup

NexusPipeline is a FastAPI Docker execution engine. Clone it, compose up, and keep job state on disk you control. One payment. No worker SaaS.

Guide

Self-hosted admin dashboard setup

NexusAdmin is the self-hosted dashboard that sits next to NexusPipeline. One payment, Docker Compose, no SaaS admin tenant.

Guide

Self-hosted log stream setup

LogStream is a single-binary Node.js collector. HTTP and UDP ingest, SQLite, live dashboard, webhook alerts. One payment. No observability SaaS.

Guide

Self-hosted env sync setup

EnvSync Agent syncs .env values across VPS hosts, laptops, and microservices. Encrypted key-value store. One payment. No secrets tenant.

Guide

Self-hosted API proxy setup

API Proxy Service sits between your code and upstream APIs. Retries, rate limits, fallbacks, circuit breakers. One payment. No gateway SaaS.