HooksideBeta

← Back to Hookside

Hookside documentation

A plain-language guide for QA testers — no prior webhook experience required.

Beta: Hookside is currently in beta. Endpoint-creation limits, ingestion-rate limiting, and scheduling automatic cleanup to run in production must be completed before public launch.

What is Hookside?

A webhook is an HTTP request one service sends to another automatically when something happens — for example, a payment provider notifying your app that a charge succeeded. You don’t control when it arrives or exactly what it contains until you look.

Hookside gives you a temporary URL that can receive those requests, then shows you:

  • the request body (the payload)
  • every header
  • every query parameter
  • the response Hookside sent back, and when the request arrived

It also identifies byte-exact repeated requests — useful for spotting retries.

It is useful for testing integrations, retries, and unexpected payloads. It does not execute the submitted payload — nothing you send to Hookside is ever run, only stored and displayed.

One honest caveat: matching payload bytes do not prove two requests represent the same underlying business event — a provider could coincidentally (or intentionally) send identical bytes for two unrelated things. Hookside tells you the bytes matched; it doesn’t know what they mean.

What problem does it solve?

Normally, to see what a webhook actually contains, you’d need to stand up your own server, write code to log incoming requests, and expose it to the internet — just to look at one test payload. Hookside skips all of that: you get a working URL in seconds, with nothing to install, configure, or deploy.

How do I create an endpoint?

  1. Select “Create a free endpoint.”
  2. Give the temporary inbox a recognizable name.
  3. Save both generated links — they are shown only once.
  4. Paste the Webhook URL into the provider or service you’re testing.
  5. Send an event.
  6. Open the Private inspection link.
  7. Refresh the inbox and inspect the request.

How do I send a test request?

Every example below uses a placeholder — replace it with your own real Webhook URL first:

Set this once, then reuse it below
WEBHOOK_URL="https://your-hookside-domain.example/api/hooks/YOUR_INGESTION_KEY"

A. A basic JSON request

curl
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"event":"payment.completed","amount":4200,"currency":"usd"}'

You should see: method POST, content type application/json, result 202 Accepted, classified as New request, with the JSON payload and headers visible on its detail page.

B. A repeated request

Send the exact same request a second time:

curl (send twice)
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"event":"payment.completed","amount":4200,"currency":"usd"}'

curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"event":"payment.completed","amount":4200,"currency":"usd"}'

The second one appears as Repeated request and links to the original matching request. This is byte-exact matching — even changing whitespace or reordering fields changes the raw bytes and may classify it as New instead.

C. Query parameters

curl
curl -X POST "$WEBHOOK_URL?source=checkout&environment=test" \
  -H "Content-Type: application/json" \
  -d '{"event":"checkout.started"}'

source and environment appear under Query parameters on the delivery detail page.

D. Plain text

curl
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: text/plain" \
  --data 'QA smoke test'

Webhook bodies don’t need to be JSON — Hookside stores and displays the exact bytes either way.

E. Custom headers

curl
curl -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -H "X-Provider-Event-Id: evt_123" \
  -H "X-Test-Environment: staging" \
  -d '{"event":"user.updated"}'

Custom headers like these appear under Headers on the delivery detail page, exactly as sent.

What should I expect to see?

After sending a request and refreshing the inbox, you’ll see it listed, and its detail page shows:

Method
The HTTP method used to send the request — POST, PUT, PATCH, or DELETE.
Result
The HTTP status code Hookside returned for this request, e.g. 202 Accepted.
Content type
The Content-Type header the sender declared, if any — for example application/json or text/plain.
Body size
The exact size of the raw request body, in bytes.
Processing time
How long Hookside took to accept and store the request, in milliseconds.
Headers
Every HTTP header the sender included, exactly as received.
Query parameters
Everything after the ? in the webhook URL you sent to, in the order it was sent.
Payload
The request body — shown as formatted JSON when it parses as JSON, and always available as raw UTF-8 text or hexadecimal too.
New request
A request whose exact raw bytes have not been seen before on this endpoint (within the matching window).
Repeated request
A request whose raw bytes exactly match an earlier request on this endpoint. See How do New and Repeated requests work? below.
View original request
A link from a Repeated request to the first (canonical) request that shares its exact bytes.
Advanced technical details
An optional, collapsed section with the underlying classification value and the raw body's SHA-256 hash, for anyone who wants it.

What do the response codes mean?

Hookside returns one of five status codes for every webhook request it receives:

CodeMeaning
202 Accepted

Success

The request was accepted and stored. This is what you should see for a normal test request.

404 Not Found

Unknown, disabled, or expired

The endpoint URL is unknown, disabled, or expired. Hookside deliberately does not reveal which of these it is — all three look identical from the outside.

413 Payload Too Large

Body too big

The request body exceeds the configured size limit. It is not stored — nothing about an oversized request is kept.

429 Too Many Requests

Quota reached

The temporary endpoint has already accepted 25 requests, so this one is rejected and not stored. Existing requests remain fully available; nothing is deleted.

503 Service Unavailable

Could not store the request

Hookside could not safely persist the request. Nothing internal is exposed in the response — try again in a moment.

Hookside never includes internal error codes or stack traces in a response — only the status above.

How do New and Repeated requests work?

  • A request is New the first time its exact raw bytes are seen on an endpoint.
  • A request is Repeated when its raw bytes exactly match an earlier request on the same endpoint, within the matching window.
  • Matching compares raw bytes only — headers, query parameters, and content type are ignored for this comparison.
  • A Repeated request links to the original (“canonical”) request that started its group.
  • This is evidence bookkeeping, not proof of business meaning — see the caveat under What is Hookside? above.

What are the limits?

  • Maximum 25 accepted requests per temporary endpoint.
  • The endpoint expires 24 hours after it was created in the database.
  • Reaching 25 requests stops new ingestion, but does not delete anything already captured early.
  • The endpoint and everything it captured become inaccessible immediately once it expires.
  • Expired endpoint data is removed automatically by a scheduled cleanup process, not necessarily at the exact instant of expiry.
  • A rejected request (see response codes above) is never stored.
  • There is no account recovery. Losing the private inspection link means losing access to that inbox.

Each temporary endpoint stores up to 25 accepted requests and becomes unavailable 24 hours after creation. Expired endpoint data is removed automatically. Reaching the request limit stops new requests but does not remove existing data early.

Current status: the 25-request cutoff and the 24-hour expiry are both enforced today — request 26 is rejected and never stored, and once an endpoint expires its ingestion URL and private inbox link both stop working immediately, behaving exactly like an unknown endpoint. Physical deletion of expired data is implemented as a scheduled cleanup command; whether it is actually running on a recurring schedule against this deployment depends on how the operator configured it — see the beta notice at the top of this page.

What should I do if something does not work?

“I sent a webhook but nothing appeared.”

Double-check the exact Webhook URL, confirm the provider actually sent the event, check its method/body/header configuration, then refresh the inbox.

“I received 404.”

Confirm the endpoint hasn’t expired and the URL is typed exactly as shown — a 404 covers unknown, disabled, and expired endpoints alike.

“I received 413.”

Your request body is larger than the configured limit. Send a smaller test payload.

“I received 429.”

The endpoint has reached its 25-request limit. Create a new temporary endpoint to continue testing.

“My request is marked Repeated.”

Its raw bytes exactly match an earlier request. Follow the “View original request” link to compare them.

“I lost my private inspection link.”

There is no recovery path. Create a new endpoint and use it going forward.

“The payload is not shown as JSON.”

That’s expected for plain text or malformed JSON — the raw evidence is still shown exactly as received, as UTF-8 text or hexadecimal.

“Copy button failed.”

Some browsers block Clipboard API access in certain contexts. Select the text manually and copy it with your keyboard shortcut instead.

What security and privacy limitations should I know?

  • The private inspection link is a bearer secret — anyone who has it can read the inbox, the same way anyone with a password can log in.
  • Raw tokens are never stored anywhere in Hookside — only their hashes. If you lose a link, Hookside genuinely cannot recover it for you.
  • Because both links live in a URL path, they can end up in browser history, proxy logs, or anywhere a URL might normally be recorded — treat them like passwords.
  • Never send real credentials, production secrets, or real user data to a temporary Hookside endpoint. Use synthetic test data only.
  • Hookside is currently in beta. Endpoint-creation limits, ingestion-rate limiting, and scheduling automatic cleanup to run in production must be completed before public launch.