Manual testing catches obvious issues, but CI is where webhook regressions should fail fast. The SDK gives you a repeatable pattern: create endpoint, trigger behavior, wait for a matching webhook, assert payload, delete endpoint.
Why CI webhook tests matter
Most webhook bugs are contract bugs: missing headers, wrong event names, and payload shape drift. Unit tests usually miss these. Integration tests with captured real HTTP requests do not.
1. Install and configure auth
npm install @webhooks-cc/sdk
# GitHub Actions
env:
WHK_API_KEY: ${{ secrets.WHK_API_KEY }}Keep API keys in CI secrets only. Never commit them in repo config files.
2. End-to-end test flow
import { WebhooksCC, matchAll, matchMethod, matchBodyPath } from "@webhooks-cc/sdk";
const client = new WebhooksCC({ apiKey: process.env.WHK_API_KEY! });
it("emits payment.success webhook", async () => {
const endpoint = await client.endpoints.create({ name: "ci-payments" });
try {
await triggerPaymentFlow({ webhookUrl: endpoint.url });
const req = await client.requests.waitFor(endpoint.slug, {
timeout: "30s",
match: matchAll(
matchMethod("POST"),
matchBodyPath("event", "payment.success")
),
});
expect(req.headers["content-type"]).toContain("application/json");
} finally {
await client.endpoints.delete(endpoint.slug);
}
});3. Use strict matchers
- Match HTTP method first.
- Match event name from body path.
- Match provider signature header when relevant.
- Avoid broad matches that pass on unrelated requests.
If your service emits multiple webhooks per flow, add one assertion per event type instead of one broad assertion.
4. Cleanup and isolation
Endpoint-per-suite is usually enough. If tests run highly parallelized, move to endpoint-per-test or add unique endpoint names for each run.
Continue with AI-assisted webhook debugging with MCP.