What tenants are for
White-label the notifications each customer receives
White-label the notifications each customer receives
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.
Let each customer set their own notification defaults
Let each customer set their own notification defaults
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.
Give one customer a different version of a message
Give one customer a different version of a message
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.
Notify everyone in a customer's organization
Notify everyone in a customer's organization
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 .Model teams, projects, or workspaces inside your product
Model teams, projects, or workspaces inside your product
A tenant doesn’t 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 isn’t
A tenant isn’t 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 isn’t an environment. Use to separate test traffic from production. Tenants divide your customers, not your pipeline. Tenant membership isn’t 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 doesn’t 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.How tenant context resolves
Courier can apply a tenant you didn’t name. If a user belongs to exactly one tenant and your send doesn’t specify one, Courier loads that tenant’s context anyway. This is a workspace setting, useful for console, list, and audience sends where the tenant isn’t explicit in the request. See . A tenant-scoped inbox message appears only to a client signed in with that tenant. A message sent withtenant_id: "acme-corp" shows up once the client calls signIn with the same tenantId. Signing in without it returns an empty feed for that tenant, even though the send succeeded.
Tenant hierarchy merges up to four levels. Courier loads tenant context as a four-layer sliding window, starting at the tenant you sent to rather than the root. In a five-deep tree, the top tenant’s settings don’t apply to a leaf send.
Limits & behavior
Channels, providers, and API keys are shared across tenants. Configure a provider such as SendGrid once, and every tenant uses it. A customer’s own Slack token or Teams webhook can still live in the tenant’suser_profile, which merges into the recipient at send time.
FAQ
Do I need tenants for a single-customer app?
Do I need tenants for a single-customer app?
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.
Does a tenant need its own template for every notification?
Does a tenant need its own template for every notification?
A tenant inherits every workspace template by default. Create a only for the messages that customer needs to differ.
Can a user belong to more than one tenant?
Can a user belong to more than one tenant?
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 .Where do I put the tenant on a send?
Where do I put the tenant on a send?
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.