.api.
The shape
Every webhook event accepts anafter hook, which runs once the event is saved to your database. Inside it you have the full corsair instance:
These examples assume
multiTenancy: true (the quick-start setup), so they scope each call with corsair.withTenant(ctx.tenantId). On a single-tenant instance, drop withTenant and call the plugin .api directly.corsair.ts
await:
if statements.
Filtering with before
Use before to drop events you don’t care about. Throwing stops processing, and the event isn’t written to your database:
corsair.ts
before is cheaper than filtering in after, since it avoids the write.
Slow work belongs in a queue
Webhook senders expect a fast response. If a step calls an LLM, sends email, or generates a report, hand it to a job queue and return:corsair.ts
inngest/functions.ts
ctx.tenantId through to the job, since the queue worker runs outside the request and has to re-scope itself. Adapters for Inngest, Temporal, Trigger.dev, and Hatchet all follow this shape.
Multi-tenant workflows
Hooks receive the tenant onctx, so one definition serves every customer:
Checklist
- Events you don’t want are rejected in
before, not ignored inafter. - Anything slow is queued; hooks return quickly.
ctx.tenantIdis threaded through to background jobs.- Per-tenant destinations come from your settings, not constants.
- Hooks are idempotent where the provider may redeliver an event.
What’s next
Workflows guide
More patterns, including Slack to GitHub and multi-step chains.
Webhooks setup
Get a tunnel running and register your first endpoint.
Hooks reference
The full before/after API surface.
Dashboard
Surface what your workflows produced.