Webhook operations, with a way forward
Your webhooks deserve a second chance.
Receive, inspect, and recover the webhooks your application depends on. Keep the original payload, understand each failed delivery, and replay when your handler is ready.
POST https://hooks.shellorbit.com/e/{ingest_key}
202 Accepted, stored before the reply
Verifies signatures from
- Stripe
- GitHub
- Shopify
- Paddle
- Clerk
- Resend
- Svix
- Dodo Payments
An event. Every attempt. One clear trail.
See the story behind each delivery.
Inspect what arrived, follow each retry, and recover with confidence when your handler is ready.
Explore the event log →| Source | Event | State | Attempts |
|---|---|---|---|
| stripe | invoice.paid | delivered 200 | 1 |
| github | push | delivered 200 | 1 |
| stripe | charge.refunded | delivered 200 | 3 |
| shopify | orders/create | delivered 200 | 2 |
Delivery attempts for evt_9c41f0
- 12:04:01 Attempt 1 returned 502 from api.yourapp.com
- 12:04:09 Attempt 2 returned 502, next try in 32 seconds
- 12:04:41 Attempt 3 in flight Attempt 3 returned 200 in 240 ms
For the terminal you already have open
One URL in. Signed requests out. An API for the rest.
Everything the dashboard does is a plain HTTP call, and none of it needs an SDK. Copy an example, set your own key, run it.
- Ingest
POST /e/{ingest_key}, 202 once stored- Delivery
- At least once, signed with HMAC SHA256
- Retries
- 5 on Hobby, up to 50 on paid plans
- Replay
- One event or a range, 15 to 180 days back
- Verify
- Stripe, GitHub, Shopify, Paddle, Standard Webhooks
- Payloads
- Up to 5 MB, kept byte for byte
Receive
# Your provider calls this URL. So can you, to try it.
curl -X POST "https://hooks.shellorbit.com/e/$INGEST_KEY" \
-H "content-type: application/json" \
-d '{"type":"order.created","id":"ord_123"}'HTTP/2 202
{"id":"evt_01m4d6rgyr4pfks4hy1fbpkz3b","received_at":"2026-10-08T09:30:00Z"}The event is stored before the 202 goes back, then delivered to your destinations with retries.
Quickstart →Verify
import crypto from "node:crypto";
// Every delivery carries ShellOrbit-Signature: t=<unix>,v1=<hex>
export function verify(rawBody, header, secret, toleranceSeconds = 300) {
const pairs = header.split(",").map((part) => part.split("="));
const t = pairs.filter(([name]) => name === "t").map(([, value]) => value);
if (t.length !== 1 || !/^\d+$/.test(t[0])) return false;
const timestamp = Number(t[0]);
if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;
const expected = crypto.createHmac("sha256", secret)
.update(`${timestamp}.`).update(rawBody).digest();
return pairs.filter(([name]) => name === "v1").some(([, value]) =>
/^[a-f0-9]{64}$/i.test(value || "") &&
crypto.timingSafeEqual(expected, Buffer.from(value, "hex")));
}HMAC SHA256 over the timestamp and the raw body. During a key rotation both signatures are sent, so any match passes.
Signature verification →Replay
# Fixed the handler? Send the stored event again, byte for byte.
curl -X POST "https://api.shellorbit.com/v1/events/$EVENT_ID/replay" \
-H "authorization: Bearer $SHELLORBIT_API_KEY"HTTP/2 202
{"event_id":"evt_01m4d6rgyr4pfks4hy1fbpkz3b","queued":1}One event, or a filtered range with POST /v1/replays. Replay works for as long as your plan keeps the event.
Replay and recovery →Send
# Send your own webhooks through the same pipeline.
curl -X POST "https://api.shellorbit.com/v1/endpoints/ep_example/events" \
-H "authorization: Bearer $SHELLORBIT_API_KEY" \
-H "content-type: application/json" \
-d '{"type":"invoice.paid","data":{"id":"inv_123"}}'HTTP/2 202
{"id":"evt_01m4d6rhv21wcmh9zs3p3kmp48","received_at":"2026-10-08T09:31:06Z"}Stored, signed, retried, and replayable like any received event. Your API key is never forwarded.
Sending events →Localhost
curl -O https://shellorbit.com/downloads/shellorbit-listen.mjs
export SHELLORBIT_API_KEY=your_read_only_key
node shellorbit-listen.mjs ep_example http://localhost:3000/webhooksForwarding new events on ep_example to http://localhost:3000/webhooks. Press Ctrl+C to stop.
evt_01m4d6rgyr4pfks4hy1fbpkz3b checkout.session.completed -> 200 in 41 msReal provider traffic on your machine, original headers and body, no tunnel. A read only key is enough.
Local development →A clearer path from failure to recovery
Know what arrived.
Understand what happened next.
A failed webhook should leave a trail you can follow. ShellOrbit gives each event a payload, a delivery history, and a way forward.
A home for every accepted event
Give your provider one HTTPS URL. Keep receiving while your application is busy or unavailable.
Explore receiving → 02 / INVESTIGATEThe details behind a failure
See the request, response status, timing, and attempts together. Filter the noise out of your event log.
Explore event history → 03 / RECOVERRetries with a deliberate next step
Let automatic retries handle interruptions. Inspect exhausted events and replay after fixing the cause.
Understand reliability →Built around your existing handler
A small change at the edge.
A much clearer event trail.
Point your provider at ShellOrbit and set your application as the destination. Keep your application’s business logic where it belongs.
A practical starting point
Start free.
Grow when your traffic does.
15,000 monthly events and 15 days of history on Hobby. Paid plans add volume, longer retention, and more control.
Find your planStart with one provider
Give your next webhook a clear destination.
Create an endpoint, connect your handler, and send a test event.