withTenant().
Enable it
corsair.ts
multiTenancy: true, Corsair won’t let you call plugins directly — every operation must go through withTenant(). This is enforced at the type level, so you’ll get a compile error if you forget.
Use withTenant()
Pass any stable user identifier — database ID, auth provider ID, anything:
How Corsair scopes it
When you callwithTenant('user_abc123'), Corsair:
- Adds
tenant_id = 'user_abc123'to everyINSERT— all data written is tagged - Adds
WHERE tenant_id = 'user_abc123'to everySELECT— you only ever read your own data - Retrieves credentials scoped to that tenant — API calls use that user’s token, not yours
- Routes incoming webhooks to the correct tenant via
?tenantId=user_abc123in the URL
Per-user credential setup
Each user connects their own accounts. Store credentials when they authenticate:auth-callback.ts
Webhooks
When registering webhooks, include the user’s ID in the URL:tenantId from the query string and automatically scopes the database write to that user. No routing logic on your end.
What’s next
Webhooks
How to scope incoming events per tenant using the ?tenantId= param.
Vibe Code Your Dashboard
Scaffold a Next.js app that uses Corsair with multi-tenancy.