Skip to main content
You receive POST callbacks from any external service (payment gateways, GitHub, CRMs, etc.), validate the payload, and process the event. Pattern: custom route + POST only + MCP disabled + payload validation.
index.ts

Local testing

Why it works this way

  • config.methods: ["POST"] — rejects GET, PUT, etc. Webhooks are always POST.
  • config.mcp: false — there is no point in exposing a webhook as an AI tool.
  • config.path — fixed route that you configure in the external service.
  • The input schema validates the payload structure before it reaches the handler.

Verify the webhook signature

A public function can be called by anyone who knows the URL. In production, verify the service’s signature before processing the event — ctx.verify* does it in one line:
If the signature does not match, it throws and the event never reaches your logic. For Stripe, Shopify and Meta use each provider’s verifier, which already knows its header and secret:
Set the secret before deploying: jelou functions secrets set my-webhook WEBHOOK_SECRET=whsec_...

Webhooks guide

Supported providers, secret rotation, error codes and testing.