{"openapi":"3.1.0","info":{"title":"Hookwire API","version":"0.1.0","description":"Hookwire is a webhook relay — like smee.io but built on Cloudflare Workers.\n\n## How it works\n\n1. **Get a channel URL** — visit the homepage or pick any random string.\n2. **Paste it into your provider** — GitHub, Stripe, Linear, or any webhook sender.\n3. **Watch events in real-time** — open the viewer page or connect via WebSocket.\n\nNo API keys, no tokens, no setup. The URL is the only credential.","contact":{"name":"Hookwire","url":"https://hookwire.dev"}},"servers":[{"url":"https://hookwire.dev","description":"Production"},{"url":"http://localhost:8787","description":"Local"}],"tags":[{"name":"Ingest","description":"Webhook receive endpoint"},{"name":"Events","description":"History + WebSocket"}],"components":{"schemas":{"ApiError":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["ok","error"]},"ChannelEvent":{"type":"object","properties":{"id":{"type":"string"},"seq":{"type":"number"},"received_at":{"type":"string"},"method":{"type":"string"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"type":"object","properties":{"encoding":{"type":"string","enum":["utf8","base64"]},"content_type":{"type":"string","nullable":true},"data":{"type":"string"},"size":{"type":"number"},"truncated":{"type":"boolean"}},"required":["encoding","data","size","truncated"]},"summary":{"type":"object","nullable":true,"properties":{"title":{"type":"string"},"subtitle":{"type":"string","nullable":true}},"required":["title"]}},"required":["id","seq","received_at","method","headers","body"]}},"parameters":{}},"paths":{"/ch/{name}":{"post":{"tags":["Ingest"],"summary":"Ingest a webhook","description":"Receives a webhook from any external service. No auth required — the channel name is the only credential. Supports any content type.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"Your channel name"}],"responses":{"202":{"description":"Webhook accepted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"event_id":{"type":"string"},"seq":{"type":"number"}},"required":["ok","event_id","seq"]}}}},"413":{"description":"Body too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/ch/{name}/events":{"get":{"tags":["Events"],"summary":"Get event history","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"after_seq","in":"query","schema":{"type":"integer"}},{"name":"include_body","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Events","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"channel":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/ChannelEvent"}}},"required":["ok","channel","events"]}}}}}},"delete":{"tags":["Events"],"summary":"Clear all events","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cleared"}}}},"/ch/{name}/ws":{"get":{"tags":["Events"],"summary":"WebSocket connection","description":"Upgrade to WebSocket for real-time event streaming. Server sends `hello`, `event`, `pong` messages.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"101":{"description":"WebSocket upgrade"},"429":{"description":"Too many connections"}}}},"/ch/{name}/sse":{"get":{"tags":["Events"],"summary":"Server-Sent Events","description":"Stream events via SSE. Internally bridges to the ChannelDO WebSocket for real-time push. Use `EventSource` in the browser to connect.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SSE stream (text/event-stream)"}}}}}}