setupCorsair from your backend (on signup, in production) and pnpm corsair setup from the CLI (local and ops). Both are idempotent, so they skip rows that already exist.
Data model
Account rows are created only for plugins with an
authType (api_key, oauth_2, bot_token, managed). A tenant is any stable ID you choose: user id, org id, workspace slug.
Provisioning touches only these two credential tables. The other three (entities, events, permissions) are covered under Database and Permissions.
setupCorsair
Call it from your backend, most often on signup, with no deploy per tenant.onboarding.ts
What it creates
CLI
Same provisioning from the terminal, for local setup and ops:Credentials
Integration-level: shared OAuth app creds, one per plugin:api_key / bot_token fields and OAuth tokens:
keys.set_*() needs an account row first. Run setupCorsair({ tenantId }) before setting API keys.
Multi-tenant
corsair.ts
Every runtime call goes through
corsair.withTenant(id). See Multi-tenancy.
OAuth
Provisioning does not run OAuth; it prepares the rows. Tokens arrive when a user connects. After integration creds are set:corsair.manage.connect.oauthCallback stores the tokens and creates the account row lazily if missing. This is the OAuth-only path. You can skip setupCorsair({ tenantId }) on signup and let the first connect provision the row. API keys still need setupCorsair first.
Adding a plugin later
Plugins come fromcreateCorsair({ plugins: [...] }), so adding one is a code change and deploy. After deploying:
corsair.manage.tenants.create() records a tenant but does not create account rows. Use setupCorsair or the CLI to provision.