Webhooks out. Webhooks in. Same terminal.

Ship signed events from a schema-generated client, and stream everyone else's webhooks straight to localhost. Five commands out. One command in.

For developers adding customer-facing webhooks to an existing application.

~/acme-apirepost CLI
$repost schema init
created schema/billing.repost · registry linked
$repost schema validate
✓ schema valid · 2 events · 0 problems
$repost schema migrate dev --name add_customer
created migrations/20260711_1140_add_customer/
$repost schema generate
client written → @repost/client · typed methods: 2
$repost schema migrate deploy --env production
✓ deployed · registry v15
$node src/send-first-event.ts
→ customer.created delivered · signature v1 · 200 OK
$repost init
created bucket acme-hooks · forwarder → localhost:3000
$repost forward
listening on acme-hooks.repost.sh → localhost:3000
← POST /stripe/invoice.paid → 200 · 43ms
first delivery out · first capture inone CLI · both directions

the whole session · nothing skipped

Send

From an empty directory to the first signed delivery.

  1. 01

    Initialize

    Run repost schema init and define the first catalog event and payload model.

  2. 02

    Validate and migrate

    Format the schema, validate it locally, and create a reviewable migration.

  3. 03

    Generate and deploy

    Generate the TypeScript client and deploy the migration to an environment.

  4. 04

    Send

    Call the generated webhook method with a customer ID and typed data.

Receive

The webhook hits prod. Your breakpoint catches it.

repost forward streams a bucket straight to localhost, live or with the backlog you missed while you slept. repost replay re-fires any capture until your handler behaves.

In CI, repost expect blocks until the webhook you're testing for actually arrives. A real assertion, not a sleep().

No tunnel anywhere in that loop: forwarding webhooks to localhost without a tunnel, four steps end to end.

Terminalrepost forward

Listening on acme-hooks.repost.sh localhost:3000

TimeMethodPathCodeStatusDuration
14:05:18.412POST/stripe/invoice.paid200SUCCESS43ms
14:05:14.205POST/github/pull_request.opened200SUCCESS95ms
14:05:11.998POST/stripe/charge.failed402FAILED51ms
14:05:09.122POST/twilio/message.delivered200SUCCESS58ms
stored before it's acknowledged↑↓ select · enter inspect · r replay

$ repost forward -b acme-hooks -f local-webhooks

From schema to delivery

Both directions of webhooks. Not two vendors.