Skip to main content
Ship a Notifications tab in your product. Each customer edits their own emails, and your send never changes. Every edit belongs to that customer’s tenant. You mount the editor, scope a token to one tenant, and keep sending one template that resolves differently for each of them.

What you will build

Prerequisites

  • A React app on 18.2.0 or newer

Seed the tenant’s template

Do this when your app creates the org. The editor opens on your wording instead of an empty page, and the send has content before anyone edits anything. The template_id is an id you choose. Use the same one for every tenant, so your send never branches. Every element sits inside a channel block, the same rule follow.
The full lifecycle of a tenant template, including versions and deletes, is in .

Put the editor in your app

1

Install the package

2

Issue a token scoped to one tenant

The editor runs in the browser, so it authenticates with a JWT rather than your API key. Mint one on your backend for the admin who is signed in, scoped to the tenant they belong to.
Read the tenant id from your own session, never from the browser. A token carrying tenants: in place of tenant:acme-corp: grants every customer at once. Every scope is listed in .
3

Mount the editor on your settings page

TemplateProvider takes the template id you seeded, the tenant, and the token. brandEditor puts logo, colors, and footer beside the content, so one screen covers both.
routing limits which channels the customer sees. Leave it out and they get every channel your workspace sends on. Every prop is in .
4

Publish on your own terms

The editor auto-saves a draft and ships its own Publish button. Hide that button when publishing should run through your own review or your own UI, then call the hook.
Render it beside <TemplateEditor hidePublish />. A draft the customer never publishes does not reach anyone, so the send keeps using the last published version.

Send what the customer published

1

Name the tenant's template

Reference it as tenant/<template_id> and set the tenant in the context. The word tenant is literal, and your tenant id goes in context.tenant_id.
This is the whole payoff. The call is identical for every customer, and only tenant_id changes.
2

Reach the whole org

Swap to for a tenant_id and Courier sends to every member of that org, still in their own content and brand. covers each targeting shape.

Verify

1

Edit as a customer would

Open your settings page signed in as a user of acme-corp, change a line of copy and the logo, then publish.
2

Read the template back

and confirm the published content carries the edit.
3

Send and compare two orgs

Send to a user in acme-corp and a user in beta-inc, then open both in . Same call, same template id, two different messages.

Troubleshooting

Brand, defaults, and templates all resolve from the same tenant, in the order set out in . To give a customer their own defaults as well as their own copy, see .