# Overview

> Source: https://truto.one/docs/guides/tenants/overview/

A tenant represents one of your end-users (or customers, or workspaces — whichever unit you connect integrations for) inside Truto. Every integrated account is owned by a tenant, and everything you send to third-party APIs through Truto is billed, logged, and rate-limited under the tenant that owns the account.

## What is a Tenant?

A tenant is a lightweight, environment-scoped object that groups all the integrated accounts belonging to one of your end-users. You choose the ID — a string like `acme-corp`, `usr_1a2b3c`, or the UUID your own database uses — and Truto keeps that same ID with the tenant across every integration your user connects.

One tenant can own many integrated accounts: your customer "Acme Corp" might connect HubSpot, Salesforce, and Slack, and each of those becomes an integrated account under the same tenant. Filtering `GET /integrated-account?tenant_id=acme-corp` returns all three.

## Tenants and Environments

Tenants are scoped to an environment. The same `tenant_id` value can exist in `development`, `staging`, and `production` independently — three separate tenant rows with three separate sets of connected accounts. That's the same isolation model as [Environments](/docs/guides/environments/overview): what's in one environment isn't in the others.

Because of that scope, the composite primary key of a tenant is `(id, environment_id)`. The dashboard handles environment scoping automatically; API tokens are bound to a single environment, so you don't need to pass `environment_id` manually in API calls.

## Tenant IDs

You pick the ID. Truto accepts anything URL-path-safe up to 255 characters — letters, digits, and the characters `. _ : @ + -`. No spaces, no slashes.

Common choices:

- The primary key from your own users/organizations table (`user_1a2b3c`, `org-4567`).
- A slug your customer will recognize (`acme-corp`).
- The email domain, when you have one workspace per company (`acme.com`).

Whatever you pick, treat it as immutable: it's referenced by every integrated account owned by that tenant, every link token created against it, every log line, and every webhook payload.

## Where Tenants come from

There are three ways a tenant appears in Truto:

- **You create it explicitly** — via the dashboard, the API (`POST /tenant`), the CLI (`truto tenants create`), or in bulk (`POST /tenant/bulk`). This is the recommended path when you're onboarding a new customer.
- **Truto auto-creates it during a connection** — when an integrated account is created with a `tenant_id` that doesn't exist yet, and the ID matches the allowed pattern, Truto materializes the tenant row for you. Creating a link token alone does not create the tenant — your customer's first successful connection does.
- **You bulk-import a batch** — from CSV or JSON. Useful when moving from another system or seeding staging with a known set of customers. See [Bulk import](/docs/guides/tenants/bulk-import).

Explicitly creating tenants first gives you a place to attach metadata (tier, region, billing plan) before the customer connects anything. If you don't need that, letting Truto auto-create them is fine.

## Metadata

Tenants carry a free-form JSON `metadata` field. Truto stores it as-is; nothing in it changes platform behaviour. Use it for anything your team wants alongside the tenant record:

```json
{
  "tier": "gold",
  "region": "wnam",
  "signed_up_at": "2026-06-01",
  "billing_email": "billing@acme.com"
}
```

Metadata is returned on every `GET /tenant` / `GET /tenant/:id`.

## Managing tenants

- **Dashboard** — [Tenants](https://app.truto.one/tenants) — table view with per-tenant account counts, edit, delete, bulk import, and per-tenant detail with bulk-delete of connected accounts.
- **API** — `POST /tenant`, `GET /tenant`, `GET /tenant/:id`, `PATCH /tenant/:id`, `DELETE /tenant/:id`, and `POST /tenant/bulk`. See [Creating tenants](/docs/guides/tenants/creating-tenants) and [Deleting tenants](/docs/guides/tenants/deleting-tenants).
- **CLI** — [`truto tenants ...`](/docs/cli/admin-resources#tenants), including `truto tenants create-bulk` for batch imports.

## FAQ

**Can the same `tenant_id` appear in multiple environments?** Yes. `acme-corp` in `development`, `staging`, and `production` are three separate tenants with three separate sets of accounts — that's the environment isolation model.

**Do I have to create the tenant before my customer connects an account?** No. If you call `POST /link-token` (or create an integrated account directly) with a `tenant_id` that doesn't exist, Truto creates the tenant when the integrated account is created — as long as the ID matches the allowed pattern. Minting the link token alone does not materialize the tenant. Pre-creating gives you a place to attach metadata; auto-create is fine when you don't need that.

**What if my legacy tenant IDs have characters like `/` in them?** Auto-create only fires for IDs that match `[A-Za-z0-9._:@+\-]{1,255}`. IDs outside that pattern still work as strings on integrated accounts, but Truto won't materialize a tenant row for them. Migrate to a compatible ID scheme (or create the tenant explicitly with a compatible ID and re-point the account) to get first-class tenant management.

**Can I rename a tenant's ID?** No — the ID is the primary key. You can change the display `name` and `metadata` on `PATCH /tenant/:id`, but the ID is immutable. If you need a different ID, create a new tenant and migrate integrated accounts to it before deleting the old one.

**Can I delete a tenant with connected accounts?** No — the API returns `409 Conflict`. Delete the accounts first (or `POST /integrated-account/bulk-delete` with `tenant_id`), then delete the tenant. See [Deleting tenants](/docs/guides/tenants/deleting-tenants).
