New Tenant Setup
Seven steps. No new Slack app, no Google Cloud, no Sheets, no Railway, no scripts, no restart.
VERA runs as a single distributed Slack app that each client workspace installs into their own Slack. You do not create a new Slack app per tenant. The shared Client ID, Client Secret, and App Token are the same for every tenant — only the workspace bot token (xoxb-…) differs, and that is generated automatically when the client workspace clicks Allow during install.
1. Install VERA into the client's Slack workspace
Open <base-url>/slack/install in a browser (the same domain that hosts /admin).
Fill the form. Use the values from any existing tenant row in /admin for the three Slack fields — they're shared across all tenants.
| Field | Value |
|---|---|
| Client ID | Copy from any existing tenant row in /admin |
| Client Secret | Copy from any existing tenant row in /admin |
| App Token | Copy from any existing tenant row in /admin (xapp-…) |
| Timezone | The client's timezone |
| Google Sheet ID | Leave blank (Postgres-native) |
| Google Credentials JSON | Leave blank (Postgres-native) |
Click Install to Slack. You'll be redirected to Slack's authorization page.
On the Slack page:
- Make sure the client's workspace is selected in the top-right dropdown
- Click Allow
VERA receives the workspace's bot token, creates the tenant in Postgres, and shows a success page.
What success looks like: the page reads "VERA installed for [Workspace Name]". The tenant now appears in /admin with its Slack tokens already filled in.
2. Create the audit channel and invite the bot
In the client's Slack workspace:
- Create a channel (e.g.
#vera-audit) — private is fine - Copy the channel ID: click the channel name → About → copy the ID starting with
C - Type
/invite @VERAin the channel
What success looks like: the bot appears in the channel member list.
The channel ID starts with
C, not the channel name. Using the name will fail silently.
3. Set the audit channel ID in /admin
Back in /admin, find the new tenant row (it's already there — created automatically by the install in step 1).
- Paste the
C…ID into the Audit Channel field - Click Verify next to that field — wait for the green confirmation that the bot is in the channel
- Click Save
What success looks like: the audit channel is set, Verify is green.
4. Add the first owner
The database starts empty of people. The first owner must be added before the full smoke test will pass.
In /admin, find the new tenant row. In the Set Owner column:
- Paste the owner's Slack user ID into the input (e.g.
U0B0K62GCCV) - Click Set Owner
The status shows ✅ Created [Name] as owner on success. If the user already exists in the system with a lower role, it is promoted to owner automatically.
To find a Slack user ID: click the person's profile in Slack → ⋮ → Copy member ID.
What success looks like: the Set Owner cell shows a green confirmation. The owner can now DM VERA normally and all owner-level commands will work.
5. Seed protected projects
The PTO, Sick, and Leave projects must exist before any team member can log time off. They are not created automatically — run this once via DM to VERA from the owner account:
run setup protected projects
What success looks like: VERA confirms the three protected projects have been created. Time-off requests will now work for all users in the workspace.
6. Verify
In /admin, click Verify on the new tenant row. Six checks run automatically:
| Check | What it proves |
|---|---|
| Slack bot token | Token is valid and not revoked |
| Slack app token | Token is valid and not revoked |
| Bot DM round-trip | Bot can DM the owner and delete the message |
| Audit channel post | Bot can post to and delete from the audit channel |
| Postgres round-trip | Database is reachable and write/read/delete works |
| Dashboard query | Reporting SQL runs cleanly against this tenant's data |
All six must show green. Common failures:
- Bot DM round-trip skips or fails — add the owner user first (step 4) and re-verify
- Audit channel fails — the bot was not invited to the channel. Run
/invite @VERA(step 2) and re-verify - Token fails — re-install via
/slack/install(step 1)
What success looks like: six green checks. The tenant is fully operational.
7. Send the dashboard URL to the client
The dashboard URL was auto-generated when the tenant was created. It is visible in the /admin tenant row.
Format: https://dash.getvera.site/d/<slug>
Open it in an incognito window first — it should render the project list (empty at this point, which is correct). Send the URL to the client.
What success looks like: the client can open the URL without a login, sees their project list, and the page auto-refreshes every 60 seconds.
Removing a tenant that was added as a separate Slack app
If a tenant was created using the Create Slack app from manifest button in /admin — producing a brand-new Slack app per tenant instead of installing the shared distributed app — remove it as follows.
Step 1 — Delete the tenant row in /admin
Find the tenant row and click Delete. This removes it from the tenants file immediately. VERA stops routing messages for that workspace.
Deletion removes the entry from the tenants file only. Any Postgres rows for that tenant are not touched. For a tenant that never had real data (e.g. a mistaken onboarding) this is fine and no further DB action is needed.
Step 2 — Delete the rogue Slack app at api.slack.com/apps
- Go to api.slack.com/apps
- Find the app that was created per-tenant (it will have a different App ID from the shared app
A0AE27UD6H3) - Open it → Basic Information → scroll to the bottom → Delete App
- Confirm deletion
This revokes all tokens associated with that app and removes it from the workspace's installed apps list.
What success looks like: the tenant no longer appears in /admin, and the app no longer appears in the Slack workspace's installed apps or at api.slack.com/apps.
Notes
The database starts empty of operational data. Structural prerequisites (disciplines, tasks, time-off projects, Internal client) are seeded automatically. The first real client interaction — logging a time entry, creating a project — is the first row in the database.
One Slack app, many workspaces. VERA uses a single publicly-distributed Slack app (A0AE27UD6H3). Each client workspace installs that one app via OAuth. Do not create a new Slack app per tenant — the /admin "Create Slack app from manifest" button exists for the original one-time app creation only and should not be used during tenant onboarding.
Google Sheets are not required. New tenants are always Postgres-native. If you want to set up a client-facing reporting sheet using IMPORTRANGE, that is a separate, optional step and does not affect VERA's operation.
Legacy tenants (Sheets-first). If you are migrating an existing Sheets-based tenant to Postgres, that is a different process — see the docs/postgres-migration.md guide and the backfill script.