# AnyHook > Webhook relay for developers and AI agents. Point any webhook (Stripe, GitHub, > Shopify, or anything else) at an AnyHook inbound URL and get automatic retries, > a full event log, inspection, and one-click replay. Zero SDK. Keyless quickstart: > one curl command returns a working relay endpoint + API key, no signup. ## Quickstart (no account needed) ```bash curl -X POST https://anyhook.net/api/v1/quickstart ``` Returns JSON with: - `inbound_url`, live endpoint that receives webhooks immediately (point Stripe/GitHub/anything at it) - `api_key`, `ahk_live_...` bearer key for the full v1 API (inspect, replay, add destinations) - `claim_url`, open in a browser to keep the endpoint permanently (free plan); otherwise it expires in 7 days - `next_steps`, copy-paste curl commands for the common follow-ups Optionally pass a forwarding destination up front: ```bash curl -X POST https://anyhook.net/api/v1/quickstart \ -H 'Content-Type: application/json' \ -d '{"destination_url": "https://your-server.com/hooks", "source": "stripe"}' ``` Every event that hits an **active** app's `inbound_url` is logged (inspectable via API) and, if a destination is set, delivered with automatic retries and a re-signed `AnyHook-Signature` header (HMAC-SHA256). The inbound URL takes webhook POSTs and also answers provider setup handshakes: Meta's `GET` carrying `hub.mode=subscribe` gets `hub.challenge` echoed back automatically, even before the app is configured, so the URL can be registered with Meta first. An app is **active from creation**, with or without a destination. With none set, events are still received and logged, so the inbound URL is worth registering with a provider straight away: inspect the real payload first, wire the destination after. A **paused** app (`isActive: false`) still answers handshakes, but event POSTs are acknowledged and DISCARDED: HTTP 202 with body reason `app_inactive`, nothing stored, nothing delivered, no event log entry. The 202 placates the provider's retry logic on purpose — do not read it as success. Un-pause with `PATCH /api/v1/apps/{slug}` `{"is_active": true}`. ## Core API (Bearer ahk_live_... auth) - `POST /api/v1/quickstart`, keyless bootstrap (above) - `GET /api/v1/apps` / `POST /api/v1/apps`, list / create relay apps - `PATCH /api/v1/apps/{slug}`, set destinations, source, is_active, retry config - `GET /api/v1/events`, event log (status, attempts, latency) - `POST /api/v1/events/{id}/replay`, replay one event - `GET /api/v1/apps/{slug}/events/undelivered`, what failed - `POST /api/v1/apps/{slug}/replay-failed`, batch replay after an outage - `POST /api/v1/api-keys`, mint additional keys (scopes: full / read_only) Full spec: https://anyhook.net/openapi.json Docs: https://anyhook.net/docs Pricing (machine-readable): https://anyhook.net/pricing.md Comparisons: https://anyhook.net/compare (vs webhook.site, ngrok, Hookdeck) ## Webhook provider reference (citable, CC BY 4.0) Response budgets, retry schedules, disable thresholds and signature schemes for 17 providers, with a primary source per row. Signature data is verified against a working implementation rather than read from documentation alone. Fields we could not source are null rather than guessed. Human: https://anyhook.net/providers JSON: https://anyhook.net/providers.json ## MCP server (for Claude / Cursor / Windsurf) ```bash claude mcp add anyhook -- npx -y anyhook-mcp # no key needed ``` Zero-config: run the `anyhook_quickstart` tool to create a free endpoint + API key with no signup, the session auto-connects. 12 tools: quickstart, create/list apps, inspect events, replay, undelivered, batch replay, mock, verify, simulate. ## Remote MCP (no local process, claude.ai connectors, ChatGPT, any HTTP client) MCP endpoint: `https://anyhook.net/mcp` (streamable HTTP, stateless, POST only) Auth: standard MCP OAuth. Add the URL in claude.ai / Claude Code / Cursor and the client opens a sign-in (Google) + consent page, no key to copy. Without a browser, send `Authorization: Bearer ahk_live_...` (key from the dashboard or from `POST /api/v1/quickstart`). No bearer → 401 with resource metadata at `/.well-known/oauth-protected-resource/mcp`. Source: https://github.com/gba3124/anyhook-mcp ## Signature verification (npm) ```bash npm i anyhook-verify # verify AnyHook-Signature in 3 lines, zero deps ``` ## Guides Vendor-neutral engineering write-ups on webhook delivery. Each states the provider's documented behaviour (with links to the primary source) before it mentions AnyHook. Listed by the question it answers. Author: Owen Hsiao (https://mangocorellc.com), who builds and operates AnyHook. - How do I stop a Calendly webhook retry from creating a double booking?: [Double Booking: What a Webhook Retry Looks Like to a Real Person](https://anyhook.net/blog/double-booking-webhook-retries) - Why didn't my GitHub webhook arrive, and does GitHub retry failed deliveries?: [GitHub Webhook Not Received: You Get One Attempt and Three Days](https://anyhook.net/blog/github-webhook-not-received) - Why do HubSpot webhooks arrive out of order, and is eventId safe to dedupe on?: [HubSpot Tells You Its eventId Is Not Unique. Believe It.](https://anyhook.net/blog/hubspot-webhook-out-of-order) - What happens if I miss an access-revoked webhook from my identity provider?: [A Dropped Revocation Webhook Is a Security Incident, Not a Data Gap](https://anyhook.net/blog/missed-revocation-webhook-security) - How do Paddle and Lemon Squeezy webhook retries differ from Stripe's?: [Paddle Retries 60 Times in Three Days. Stripe Retries About Eight.](https://anyhook.net/blog/paddle-lemonsqueezy-webhooks) - Why does my Slack bot time out or reply multiple times to one message?: [Slack Gives You 3 Seconds, and Everyone Watches You Miss It](https://anyhook.net/blog/slack-webhook-3-second-timeout) - What are Twilio's webhook timeouts, and can I configure them?: [Twilio Hands You the Timeout Dial. Almost Nobody Turns It.](https://anyhook.net/blog/twilio-webhook-timeouts) - How do I receive webhooks on Cloudflare Workers without Node crypto?: [Receiving Webhooks on Cloudflare Workers, From the One We Run](https://anyhook.net/blog/webhooks-on-cloudflare-workers) - Why is my WooCommerce webhook delayed or not firing at all?: [WooCommerce Webhooks Are Not Sent When the Order Is Placed](https://anyhook.net/blog/woocommerce-webhook-not-firing) - Why did I receive the same webhook twice, and how do I make handlers idempotent?: [You Received the Same Webhook Twice. That's the Contract, Not a Bug.](https://anyhook.net/blog/duplicate-webhook-events-idempotency) - My n8n webhook isn't working, why?: [n8n Webhook Not Working: Seven Causes, Ranked by How Often They're It](https://anyhook.net/blog/n8n-webhook-not-working) - Why did Shopify delete my webhook subscription, and what is the 5-second timeout?: [Shopify Deleted Your Webhook Subscription. Here's Why 5 Seconds Is the Whole Story.](https://anyhook.net/blog/shopify-webhook-subscription-deleted) - Stripe disabled my webhook endpoint, how do I recover the missed events?: [Stripe Disabled Your Webhook Endpoint. Here's the Recovery Playbook.](https://anyhook.net/blog/stripe-webhook-endpoint-disabled) - Why does my webhook signature check fail on Vercel / Next.js, and is waitUntil durable?: [Receiving Webhooks on Vercel Without Losing Them](https://anyhook.net/blog/webhooks-on-vercel-serverless) - Should I use webhooks or polling?: [Webhooks vs Polling: Choose by Failure Mode, Not by Fashion](https://anyhook.net/blog/webhooks-vs-polling) - How do I give an AI agent an email address?: [Give Your AI Agent an Email Address in One API Call](https://anyhook.net/blog/ai-agent-email-address) - How do I turn an inbound email into a webhook?: [Turn Any Email Into a Webhook with Cloudflare Email Routing](https://anyhook.net/blog/cloudflare-email-routing-to-webhook) - How do I make a webhook delivery log tamper-evident?: [A Tamper-Evident Webhook Log: Hash Chains and a Public Anchor](https://anyhook.net/blog/tamper-evident-webhook-log) - Why do my webhook signature tests pass while production breaks?: [Your Webhook Signature Tests Prove Nothing](https://anyhook.net/blog/webhook-signature-tests-prove-nothing) - How does an AI agent receive webhooks / get its own endpoint?: [Webhooks for AI Agents: How an Agent Gets Its Own Endpoint](https://anyhook.net/blog/webhooks-for-ai-agents) - 為什麼 AI agent 需要 webhook relay?: [為什麼你的 AI agent 需要 webhook relay](https://anyhook.net/blog/ai-agent-webhook-relay-zh) - How do I debug a failing webhook in production?: [Debugging Failed Webhooks in Production Without Losing Your Weekend](https://anyhook.net/blog/debugging-webhooks-in-production) - What retry backoff and jitter should webhooks use?: [Exponential Backoff and Jitter for Webhook Retries](https://anyhook.net/blog/exponential-backoff-jitter) - How do I replay webhooks missed while my server was down?: [How to Replay a Webhook When Your Server Was Down](https://anyhook.net/blog/how-to-replay-a-webhook) - Is ngrok enough for webhooks beyond local development?: [Why ngrok Isn't Enough: Testing and Operating Webhooks Past localhost](https://anyhook.net/blog/ngrok-alternative-webhook-testing) - How long does Stripe retry a failed webhook?: [Stripe Webhook Retries: A Production Guide](https://anyhook.net/blog/stripe-webhook-retries-production-guide) - How do I verify Stripe / GitHub / Shopify webhook signatures?: [Verifying Stripe, GitHub, and Shopify Webhook Signatures](https://anyhook.net/blog/webhook-signature-verification-guide) Index: https://anyhook.net/blog · Feed: https://anyhook.net/blog/feed.xml ## Facts - Ingress: edge (Cloudflare Workers), acks once the event is durably queued (p50 ~0.4s, p95 ~1.1s), async delivery via queue - Inbound URL accepts webhook POSTs; setup handshakes (Meta GET hub.challenge) answered automatically - Apps are active from creation; a destination-less app logs events without delivering them. A paused app answers handshakes but 202-acks and discards event POSTs (body reason `app_inactive`); un-pause via dashboard or PATCH `is_active` - Retries: exponential backoff (5m / 30m / 2h / 12h), plan-based attempt counts - Free plan: 1 app, 3,000 events/month (100/day), 3-day retention, no card required - Payloads encrypted at rest (AES-256-GCM); delivery re-signed on every attempt - Replay never consumes quota