Skip to main content
A tenant is one of your customer organizations: the company, account, or workspace that a group of your users belongs to. If you sell to businesses, you already have this object in your own database, under one of those names.
One field on the send names the organization. Courier applies that tenant’s brand, defaults, and content, so one template goes out looking like it came from each of your customers.

What tenants are for

Every customer sees their own logo, colors, and sender identity. Attach a to the tenant and Courier applies it whenever you send to a user in that tenant, with no change to the template.
A tenant carries default for its topics. One customer starts opted out of product announcements, another makes billing alerts required. Their users can still change their own.
A overrides the workspace template for that tenant only. Use it when a customer needs different wording, an extra legal line, or their own layout.
Send to a tenant_id instead of a user and Courier fans out to its members. Tenants can nest through parent_tenant_id, so a send can walk the hierarchy up or down. See .
A tenant does not have to be a company. It maps to whatever unit your product bills or brands: a team, a project, a store, a region.

What you store on a tenant

Anything that is true about a customer organization rather than about a particular notification. Without a tenant, all of that gets looked up and assembled in front of every send. With one, you pass an id and Courier resolves the rest. Put event-specific values in data. Put customer-level values in the tenant’s properties. A support address that arrives in data on every send is one that belongs in properties once.

What a tenant is not

A tenant is not a way to group recipients. If what you want is “send this to these people”, use a . A tenant scopes branding and settings to one customer. To send to a group of users, use a list or an audience. A tenant is not an environment. Use to separate test traffic from production. Tenants divide your customers, not your pipeline. Tenant membership is not permissions. Being in a tenant decides which context Courier builds a message from, and nothing about what that user may do. Authorization stays in your application.

How it works

You address a user, and name the tenant that user is acting in. See for the resolution order. Anything the tenant does not define falls through to the workspace default, so you only configure the differences. A user can belong to as many tenants as you need, and each membership is independent. Someone who works with two of your customers can have alerts on at Acme and off at Beta. They see Acme’s branding in one email and Beta’s in the next, with a separate inbox feed on each side.

Three things that fail quietly

None of these raise an error, which is what makes them worth knowing before you ship. Courier can apply a tenant you did not name. If a user belongs to exactly one tenant and your send specifies none, Courier loads that tenant’s context anyway. It is a workspace setting, useful for console, list, and audience sends, and confusing the first time a customer’s branding turns up on a message you thought was unscoped. See . Tenant-scoped inbox messages are invisible to clients signed in without the tenant. A message sent with tenant_id: "acme-corp" only appears when the client called signIn with the same tenantId. Sign in without it and the feed is empty, while the send itself reports success. The fifth level of a hierarchy is dropped. Courier loads tenant context as a four-layer sliding window. It starts at most three ancestors up rather than at the root, so in a five-deep tree the top tenant’s settings never reach a leaf send.

Limits & behavior

Channels, providers, and API keys are never tenant scoped. Configure a provider such as SendGrid once, and every tenant shares it. A tenant cannot hold its own integration credentials, though it can carry a customer’s own Slack token or Teams webhook in user_profile, which merges into the recipient at send time. Keep hierarchies to four levels. Deeper than that and the sliding window above drops the root, so nothing important should sit at the top of a deep tree. Tenants work normally inside an EU workspace. Only creating a new workspace is unavailable in that region. See .

FAQ

Tenants serve multiple customer organizations from one account, as in B2B SaaS or white-label products. A single-customer app needs one workspace and no tenants.
A tenant inherits every workspace template by default. Create a only for the messages that customer needs to differ.
If the user belongs to exactly one tenant, Courier infers it. With two or more memberships you must set context.tenant_id, or the send fails with Tenant Context Not Found. See .
Either to.tenant_id on the recipient or message.context.tenant_id. Both behave identically, so pick one and put it behind a shared helper. uses the context form throughout.