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: 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_idthat 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.
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:
{
"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 — 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, andPOST /tenant/bulk. See Creating tenants and Deleting tenants. - CLI —
truto tenants ..., includingtruto tenants create-bulkfor 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.