Send & Verify Events
Develop a webhook handler with no provider account, dashboard, or real event. otterkit send fires a correctly-signed synthetic event straight at your local handler; otterkit verify tells you whether captured requests carry a valid signature. Both run entirely on your machine — the signing secret never leaves it.
Send a signed event
Pass the provider's signing secret and the event is signed exactly as the provider would sign it, so your handler's verification passes:
# Stripe — fire a signed payment_intent.succeeded at your handler
npx otterkit send stripe:payment_intent.succeeded 127.0.0.1:3000/webhooks/stripe \
--secret whsec_your_signing_secret
# GitHub, Shopify, Slack too
npx otterkit send github:push 127.0.0.1:3000/hooks/github --secret ghs_...
npx otterkit send shopify:orders/create 127.0.0.1:3000/hooks --secret shpss_...
# Customize the payload
npx otterkit send stripe:checkout.session.completed 127.0.0.1:3000/hooks \
--secret whsec_... --body '{"data":{"object":{"amount_total":19900}}}'
# List every provider and event
npx otterkit send --listWithout --secret the event is sent unsigned — useful for checking that your handler correctly rejects unsigned requests.
Verify captured signatures
The single most common webhook question is “is my signature check wrong, or is the payload wrong?”. Point verify at a capture log with the secret and it answers definitively:
npx otterkit verify myhooks stripe --secret whsec_...
# ✓ 08:14:02.101 POST /webhooks/stripe
# ✗ 08:15:11.882 POST /webhooks/stripe
# Stripe-Signature: signature_mismatchA mismatch with the correct secret means the payload was altered in transit or your body isn't the raw bytes; all-valid means your handler code is the culprit. Supported schemes: Stripe, GitHub, Shopify, Slack.
Replay with re-signing
Editing a captured signed request's body normally breaks its signature, so the handler rejects the replay. --resign re-signs the edited body so it still passes:
npx otterkit replay myhooks --set data.object.amount=999 \
--resign stripe --secret whsec_...