Docs · Quickstart

From signup to first replay in five minutes.

Create an endpoint, point a provider at it, forward what it catches to your local server, and replay it whenever you change your code.

Before you start: you need a free SlingHook account and, for step 3, Node 18.17 or newer on the machine that runs your app. Create an account and the dashboard walks you through the same four steps.

1Create an endpoint

An endpoint is a public URL that records every request sent to it. New accounts get one called My first endpoint. To add more, press + next to Endpoints in the sidebar and give it a name, such as Stripe dev.

Its catch URL looks like this. Copy it from the sidebar (hover the endpoint) or with ⌘K → Copy catch URL.

https://slinghook.example/v1/catch/3f1c9a2e-7b4d-4e8a-9c61-2d5f0e8b7a14

Free accounts have 3 endpoints. Pro and Team have no endpoint limit.

On Pro and Team you can also reserve a readable URL such as /v1/catch/stripe-dev under Endpoint settings → Reserved URL, so you paste it into your provider once and never again. Names are 3 to 40 lowercase letters, numbers and hyphens, and are first come, first served. The UUID URL keeps working alongside it. If you move back to Free, the name stays yours but only answers again once you upgrade.

2Catch your first webhook

Send anything to the catch URL and it appears in the live feed straight away. The quickest test is cURL:

curl -X POST https://slinghook.example/v1/catch/<endpoint-uuid> \
  -H "Content-Type: application/json" \
  -d '{"type": "test.ping", "status": "ok"}'

No provider set up yet? Press Simulate above the feed to send a realistic Stripe, GitHub, Shopify or Slack event, complete with a valid signature when the endpoint has a signing secret.

When you are ready for real traffic, paste the catch URL into your provider's webhook settings. The provider guides say where.

3Forward to localhost

SlingHook runs on the internet and your app runs on your laptop, so SlingHook cannot call localhost directly. The slinghook CLI opens an outbound connection instead, the same way stripe listen does, and delivers each webhook to your local server as it arrives.

Install and sign in

npm install -g slinghook

slinghook login --server https://slinghook.example

login asks for your email and password, creates a personal API token, and saves only the token. In CI or on a shared machine, create a token under User settings → API tokens and pass it with --token shk_… or SLINGHOOK_TOKEN instead.

Start forwarding

slinghook endpoints
slinghook listen <endpoint-uuid> --forward http://localhost:3000/webhooks
● Listening on endpoint 3f1c…
  Forwarding to http://localhost:3000/webhooks

14:02:11 POST   #1234 → 200 37ms sig:valid
14:02:15 POST   #1235 → ✗ Connection refused (is your local server running?) 2ms

Each webhook keeps its method, body, query string and signature headers, so your app's own signature check runs for real. Every delivery shows up in the dashboard's replay history. If the connection drops, the CLI reconnects and picks up where it left off, so nothing that arrived in the gap is lost.

Forwarding to a public URL instead? If your app is already reachable from the internet (a staging server or a tunnel), set it as the endpoint's Default forward target in endpoint settings and turn on Auto-Relay. Don't use Auto-Relay and the CLI on the same endpoint at once, or each webhook is delivered twice.

4Replay it

Changed your handler? You don't need to make the provider fire again. Select any captured request and press R (or Replay in the inspector) to send it to your forward target. The response status, body and timing are saved in the request's replay history.

  • Edit & resend changes the method, headers or body for one send without touching the original.
  • Copy as cURL gives you a command you can paste into a terminal or a bug report.
  • Code turns a payload into TypeScript, Python, PHP or Go types, a fixture file, or a test that posts it to your handler.

That's the whole loop: catch, debug, replay. The rest of this page covers the parts you'll want once a real integration is wired up.

Stripe, GitHub and Shopify

Stripe

  1. In the Stripe dashboard, open Developers → Webhooks and choose Add endpoint.
  2. Paste your catch URL as the endpoint URL and pick the events you need.
  3. Copy the endpoint's Signing secret (it starts with whsec_) into SlingHook's endpoint settings to check every signature.

GitHub

  1. In your repository, open Settings → Webhooks → Add webhook.
  2. Set Payload URL to your catch URL and Content type to application/json.
  3. Enter a secret, and save the same value in SlingHook's endpoint settings.

Shopify

  1. In the Shopify admin, open Settings → Notifications → Webhooks (or create a subscription from your app).
  2. Use your catch URL as the destination, in JSON format.
  3. Shopify signs with your app's client secret. Save it in SlingHook's endpoint settings.

Anything else that sends HTTP works too: Slack, Twilio, Paddle, WorkOS, Svix and your own services. SlingHook accepts JSON, form data, XML and plain text.

Verify signatures

Add the provider's signing secret in Endpoint settings → Webhook signing secret. SlingHook then checks the HMAC signature on every request and marks it valid or invalid in the feed. It supports Stripe, GitHub, Shopify, Slack and Standard Webhooks (Svix). Choose the provider explicitly to stop a sender from switching to a weaker scheme.

When a signature fails, click the badge. The signature debugger tells you why: the wrong kind of secret (a Stripe API key instead of whsec_…), stray whitespace in the saved secret, a stale timestamp, a body that was reformatted in transit, or a payload cut off at the size limit. You can try another secret there without saving it.

Secrets are encrypted at rest on the server.

Custom responses

By default the catch URL answers 200 OK straight away so providers don't retry. Under Endpoint settings → Simulate catch response you can return another status, a delay or a custom body, which is handy for testing how a provider retries after a 500 or a timeout. Turning an endpoint off makes it answer 410 Gone.

Scenarios

Many integrations are a sequence, such as a Stripe checkout followed by its subscription and invoice events. Save those requests as a scenario from Scenarios in the inspector, then replay the whole flow in order with the original gaps, a fixed delay, or back to back. Each step shows its status, and the run can stop at the first failure. Requests in a scenario are kept when old logs are pruned.

CLI commands

CommandWhat it does
slinghook login [--server URL] [--token shk_…]Signs in and saves an API token in ~/.config/slinghook/config.json.
slinghook endpointsLists your endpoints and their UUIDs.
slinghook listen <uuid> --forward URLForwards new webhooks to URL until you stop it. Add --no-report to keep deliveries out of the replay history.
slinghook logoutForgets the saved token. Revoke it under User settings → API tokens.

SLINGHOOK_SERVER and SLINGHOOK_TOKEN override the saved settings.

Headers SlingHook adds

HeaderWhen
X-Webhook-Replay: trueOn every replay and CLI delivery, so your app can tell them apart from first deliveries.
X-SlingHook-Log-IdOn CLI deliveries: the ID of the captured request.

Transport headers such as Host, Content-Length and Connection are dropped and recalculated. Signature headers are kept.

Limits and status codes

FreeProTeam
Endpoints3UnlimitedUnlimited
Events a month1,000100,000500,000
Request history24 hours30 days90 days

Every plan stores up to 1 MB of each request body. Bigger payloads are kept up to that size and flagged as truncated, and a truncated request can't be replayed. See pricing for the full comparison.

Status from the catch URLMeaning
200Captured. Or the status you set under custom responses.
404No endpoint has that UUID.
410The endpoint is turned off.
429Too many requests in a short burst, or a Free account has used its events for the month. Retry-After says when to try again. Paid plans keep catching past their monthly events.

Ready when your webhook is.

Free while you build. Your first endpoint is waiting.

Get a free endpoint