Skip to content

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_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.

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

  • DashboardTenants — table view with per-tenant account counts, edit, delete, bulk import, and per-tenant detail with bulk-delete of connected accounts.
  • APIPOST /tenant, GET /tenant, GET /tenant/:id, PATCH /tenant/:id, DELETE /tenant/:id, and POST /tenant/bulk. See Creating tenants and Deleting tenants.
  • CLItruto 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.