Skip to content

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.

FieldValue
Client IDCopy from any existing tenant row in /admin
Client SecretCopy from any existing tenant row in /admin
App TokenCopy from any existing tenant row in /admin (xapp-…)
TimezoneThe client's timezone
Google Sheet IDLeave blank (Postgres-native)
Google Credentials JSONLeave 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 @VERA in 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:

CheckWhat it proves
Slack bot tokenToken is valid and not revoked
Slack app tokenToken is valid and not revoked
Bot DM round-tripBot can DM the owner and delete the message
Audit channel postBot can post to and delete from the audit channel
Postgres round-tripDatabase is reachable and write/read/delete works
Dashboard queryReporting 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.