Type-Safe Routing
Handler payload types are inferred from the route schema.
Handler payload types are inferred from the route schema. Pass a Standard Schema as schema when registering a route, and the payload argument your handler receives is typed from that schema’s output — no manual type annotations or casts.
import { createWebhookRouter } from "@zap-studio/webhooks";
import { z } from "zod";
const router = createWebhookRouter();
router.register("/payments/succeeded", {
schema: z.object({ id: z.string(), amount: z.number() }),
handler: ({ payload }) => {
// payload.id: string, payload.amount: number — inferred from schema
return Response.json({ ok: true });
},
});
Handler Context
Beyond payload, every handler also receives:
request— the incoming Web APIRequest(headers, method, URL — the body stream is already consumed by the router)rawBody— the exact request body bytes as aUint8Arraypath— the matched route key (for example/payments/succeeded)
Routes Without a Schema
Registering without schema skips validation — payload is then the parsed JSON body, typed as unknown unless you declare a payload type yourself.
router.register("/ping", () => Response.json("pong"));