Webhooks - Webhook.site

Free Webhook.site Alternative

webhook.site is the inbox most developers open when they need a URL that receives a webhook: a page that shows every request as it arrives, free, with no account. The Webhook Capture API endpoint answers a narrower question, the one a script or an AI agent asks: did the sender deliver, and what exactly did it send. One POST creates a capture, the sender hits its update URL, and your code reads the request back as JSON, waits up to 25 seconds for it, or gets a signal at a URL of its own. No account, no key, HTTPS only. This page sets the two side by side, step for step, with the limits of each.

The translation

Each step a webhook.site user takes has a counterpart here. The webhook.site facts are from its own documentation, pricing and terms pages as read on 4 November 2026; where those pages give two different numbers, both are quoted.

Stepwebhook.siteaisenseapi.com
Get a URLOpen the site, or create a token through its APIPOST /services/v1/webhook_capture with an empty JSON body
What you getA unique URL, an email address and a DNS name, without signing upcapture_id, update_url, read_url, wait_url and expire_timestamp
SendAny HTTP method to the URLAny HTTP method to update_url
What the sender gets backThe URL's default response, which you can editThe capture itself, as JSON
ReadThe web page, or the requests route of its APIGET read_url: one JSON document with method, path, headers, client address and body
Wait for arrivalWatch the page updateGET wait_url, 0 to 25 seconds per call; returns early with waited_seconds and wait_reason
Be toldCustom Actions, with a subscriptionnotify_url at creation: one signal after the first request
Requests kept per URLUp to a cap on a free URL; its pages give 50 in one place and 100 in anotherOne. The first request wins, and retries return it
Body sizeUnder 10 MB256 KB
Lifetime7 days for a free URL24 hours
Email and DNS captureYesNo
Account or keyNone for a free URL; API keys belong to accountsNone
Who can read itAnyone who knows the URL's id, on a free URLAnyone who knows the capture id

The create call looks like this, and the three URLs in its answer are all you need:

curl -X POST https://aisenseapi.com/services/v1/webhook_capture \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "ok": true,
  "capture_id": "6f8c9e52-3f2c-4e73-9d3b-8d6c3f6d1c91",
  "status": "pending",
  "update_url": "https://aisenseapi.com/services/v1/webhook_capture/6f8c9e52-.../update",
  "read_url": "https://aisenseapi.com/services/v1/webhook_capture/6f8c9e52-...",
  "wait_url": "https://aisenseapi.com/services/v1/webhook_capture/6f8c9e52-.../wait/25",
  "expire_timestamp": 1772893200
}

What differs

  • One request per capture. webhook.site keeps a list of requests behind one URL. A capture here holds the first request that reaches its update URL and nothing after it: it is the proof of one delivery, not an inbox. A test that expects three deliveries creates three captures. For a stream of requests you want to browse, webhook.site is the better tool.
  • No page to look at. Every answer is JSON, written to be read by code. The same capture is also available to AI agents as the create_webhook_capture and read_webhook_capture tools of the free MCP server, so an agent can receive a callback without writing a client.
  • Built to be awaited. wait_url holds the connection for up to 25 seconds and returns the moment the request lands, and notify_url sends one signal to a URL you name, which must use a host name rather than an IP address. webhook.site answers the same need with Custom Actions on a subscription.
  • Shorter and smaller. A capture lives 24 hours from creation, against 7 days for a free webhook.site URL, and takes a body of at most 256 KB, against 10 MB. Both are enough for a webhook payload; neither is file transfer.
  • The same openness. On both services a free capture is readable by whoever knows its id, which is a long random identifier in both cases. Send test secrets only. The sender's address, every header and the complete body are stored as they arrived.

A script that waits for the callback

Create the capture, hand the update URL to the sender, then wait. One call to wait_url costs one request and returns after at most 25 seconds, so a loop that waits all day spends about 3,500 of the 5,000 requests an address has per day. For anything longer than a few minutes, give notify_url instead and let the signal come to you.

import requests

BASE = "https://aisenseapi.com/services/v1/webhook_capture"

created = requests.post(BASE, json={}, timeout=10).json()
print("Give the sender:", created["update_url"])

while True:
    answer = requests.get(created["wait_url"], timeout=35).json()
    if "request" in answer:
        break

request = answer["request"]
print(request["method"], request["uri"])
print(request["headers"])
print(request["body"])          # one of json, text or base64 is filled, with raw_length

The same three steps in curl, for a shell test:

curl -s -X POST https://aisenseapi.com/services/v1/webhook_capture -H "Content-Type: application/json" -d '{}'
# point the sender at update_url, then:
curl -s "https://aisenseapi.com/services/v1/webhook_capture/{capture_id}/wait/25"

The update call answers the sender with the capture itself, so a sender that logs its responses shows you the same document.

What a capture records

FieldTypeMeaning
captured_at_timestampintegerUnix time of the first request.
captured_at_datetimestringThe same moment in ISO 8601, UTC.
request.methodstringThe HTTP method the sender used.
request.uristringThe path the sender actually requested, query string included.
request.headersobjectEvery header received, with lower-case names.
request.client_ipstringThe sender's address as the service saw it.
request.bodyobjectjson, text or base64, exactly one of them filled, and raw_length in bytes. A request with no body is still a capture, with all three null and a length of 0.

Errors

CaseStatusWhat it means
Unknown capture id404No capture has that id.
Capture older than 24 hours410The capture has expired and its data is gone.
notify_url with an IP address as host400The signal URL must use a host name.
The day's requests used up429The shared limit of 5,000 requests per address per day; wait for the reset.

Every refusal is JSON with error and fix.

Privacy and limits

A capture stores the sender's address, every header and the complete body, so provider signatures and Authorization headers end up stored beside the payload for 24 hours, readable by anyone who holds the capture id. Use it with test credentials, and see our privacy policy for log retention.

Every path shares the service-wide ceiling of 5,000 requests per IP address per day. A full round costs three: the create call, the inbound request and your read. A capture takes one request of at most 256 KB and lives 24 hours from creation. webhook.site, for comparison, states that a free URL and its data are removed after 7 days, that a free URL stops accepting requests at its cap, and that its paid plans start at 9 dollars a month; those are its figures as of November 2026 and may change.