Tippie · Webhook

Send us data. We'll catch every request.

A no-auth POST endpoint plus a live inbox we use to inspect every payload as it lands. Use it to wire up partners, test integrations, or capture anything that needs a destination today.

Send to https://tippie.xdvu.com/hook
View at https://tippie.xdvu.com/panel basic auth Open panel →

What it is, in one paragraph

A real-world picture for the operator on the other end.

A booking platform fires customer.created events at this URL every time a salon owner finishes onboarding. Within two seconds the event appears in the inbox panel below, fully expanded — JSON pretty-printed, headers visible, source tagged. The Tippie team can copy it as a curl, replay it locally, or just confirm the partner is sending what they promised. No accounts, no schema migrations, no per-source endpoints.

At a glance

The contract any sender needs to know.

Endpointhttps://tippie.xdvu.com/hook
MethodsPOST, GET, PUT, PATCH, DELETE — all accepted
BodyAnything. JSON, form-encoded, XML, plain text, binary. Up to 20 MB.
AuthNone  Open by design — partners can post immediately.
Response200 OK with body {"ok":true,"id":N}
TaggingAppend a path segment to label the source: /hook/stripe, /hook/calendly, /hook/anything
Inspecthttps://tippie.xdvu.com/panel  basic auth

Quick start

Pick your language. Each block has a copy button.

# Minimal POST
curl -X POST https://tippie.xdvu.com/hook \
     -H 'Content-Type: application/json' \
     -d '{"event":"customer.created","email":"acme@example.com"}'

# Tagged source
curl -X POST https://tippie.xdvu.com/hook/stripe \
     -H 'Content-Type: application/json' \
     -d '{"id":"evt_123","type":"charge.succeeded"}'
await fetch('https://tippie.xdvu.com/hook/myapp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    event: 'customer.created',
    email: 'acme@example.com',
    at: new Date().toISOString(),
  }),
});
// Node 18+ has fetch built in
const res = await fetch('https://tippie.xdvu.com/hook/myapp', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ event: 'ping', n: 1 }),
});
console.log(await res.json()); // { ok: true, id: 42 }
import requests

r = requests.post(
    'https://tippie.xdvu.com/hook/myapp',
    json={'event': 'customer.created', 'email': 'acme@example.com'},
    timeout=10,
)
print(r.status_code, r.json())  # 200 {'ok': True, 'id': 43}
$ch = curl_init('https://tippie.xdvu.com/hook/myapp');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode(['event' => 'ping']),
]);
$response = curl_exec($ch);
require 'net/http'
require 'json'

uri = URI('https://tippie.xdvu.com/hook/myapp')
res = Net::HTTP.post(uri, { event: 'ping' }.to_json,
                     'Content-Type' => 'application/json')
puts res.body  #=> {"ok":true,"id":44}
body, _ := json.Marshal(map[string]any{
    "event": "ping",
})
http.Post(
    "https://tippie.xdvu.com/hook/myapp",
    "application/json",
    bytes.NewReader(body),
)

Try it now

Posts straight to the live endpoint. Open the panel in a second tab to watch it land.

Waiting…

Full route reference

Everything the service exposes.

MethodPathAuthPurpose
ANY /hook open Catch-all webhook. Returns {"ok":true,"id":N}.
ANY /hook/<source> open Same, with <source> stored as a tag on every hit.
GET /api/hits?limit=200 basic Newest-first JSON list of recent hits.
GET /api/hits/:id basic Single hit with full headers + body.
DELETE /api/hits/:id basic Remove one hit.
POST /api/hits/clear basic Truncate the table.
GET /panel basic Live HTML inbox (2-second polling).
GET /docs open This page.

What gets stored on every hit

Nothing is dropped — the raw bytes are kept so we can replay later.

  • HTTP method and the full request path (the /hook/<source> tag is split out separately).
  • All request headers, including x-forwarded-for and any custom signature headers.
  • Raw body as text, plus a parsed JSON copy when the body is valid JSON. Both are kept; the JSON view is just for prettier display.
  • Query string, caller IP, user agent, byte size, and the received timestamp (UTC).

FAQ

The questions that come up first.

Do I need an API key or auth header?

No. The webhook endpoint is intentionally open. You can post immediately. Auth is only required to inspect the inbox at /panel.

What does the source tag do?

It's a free-form label appended to the URL — for example /hook/stripe or /hook/calendly. We use it to group hits by sender in the inbox. There's no validation; pick anything memorable.

Is JSON required?

No. We store the raw body regardless of content type. JSON gets pretty-printed in the inbox automatically, but XML, form-encoded, and plain text are all accepted and visible.

What's the body size limit?

20 MB per request. Anything larger is rejected at the proxy layer with a 413.

How do I see what I sent?

Open https://tippie.xdvu.com/panel in a browser and log in. Your hit appears within ~2 seconds. The detail pane shows the full body, headers, and a "Copy as curl" button to reproduce the request.

Is this production-grade?

It's a partner-friendly catch-all, not a billing system. There's no signature verification, no per-source secrets, no retry-with-backoff, and no retention policy. If a sender needs HMAC verification, that's a fast extension on top of the existing schema — ask the Tippie team.

Does the endpoint support HTTPS only?

Yes. Plain HTTP requests redirect to HTTPS automatically. SSL is provided by Let's Encrypt.