Creating Webhook Endpoints
Each organization can register multiple webhook endpoints. When creating an endpoint, BunShip generates a unique signing secret:secret field. This is the only time the full secret is returned — store it securely on your receiving server.
Event Types and Payloads
BunShip dispatches events as JSON POST requests. Every payload follows this structure:
You can add custom event types by dispatching them through the webhook service.
Signature Verification
Every webhook delivery is signed with HMAC-SHA256. The signature is sent in theX-Webhook-Signature header using a timestamp-prefixed format that prevents replay attacks:
How signing works
BunShip creates the signature by concatenating a Unix timestamp with the raw JSON payload, then computing an HMAC-SHA256 hash using the endpoint’s secret:Verifying on your server
To verify a webhook on your receiving server:1
Extract the timestamp and signature
Parse the
X-Webhook-Signature header to get the t (timestamp) and v1 (signature) values.2
Check the timestamp
Reject requests where the timestamp is more than 5 minutes old to prevent replay attacks.
3
Compute the expected signature
Recreate the signed payload (
timestamp.body) and compute HMAC-SHA256 with your webhook secret.4
Compare signatures
Use a constant-time comparison to prevent timing attacks:
Verification example (Node.js / Bun)
Retry Logic
Failed deliveries are retried up to 3 attempts with increasing delays:
A delivery is considered failed if the receiving server returns a non-2xx status code or the request times out (30 seconds). After all retries are exhausted, the delivery is marked as permanently failed.
Delivery Tracking and Debugging
Every dispatch creates awebhookDeliveries record that tracks:
- Event type — Which event triggered the delivery
- Payload — The full JSON body sent
- Status code — HTTP response code from the receiving server
- Response — First 500 characters of the response body
- Attempts — Number of delivery attempts made
- Delivered at — Timestamp of successful delivery (null if still pending)
- Next retry at — When the next retry is scheduled
Sending a test event
Verify your endpoint is working by sending a test event:test event with a sample payload:
Delivery Headers
Each webhook request includes these headers:Secret Rotation
Rotate a webhook’s signing secret without deleting and recreating the endpoint:SSRF Protection
BunShip validates webhook URLs to prevent Server-Side Request Forgery (SSRF). The following are blocked:- Private IP ranges —
127.x.x.x,10.x.x.x,172.16-31.x.x,192.168.x.x,169.254.x.x - Localhost —
localhost,127.0.0.1,0.0.0.0,::1 - Internal hostnames — Hostnames without a dot (e.g.,
redis,postgres) - Non-HTTP protocols — Only
http://andhttps://are allowed
400 Validation Error.

