Branding And Email Templates
Configure organization branding and invitation email templates.
Branding And Email Templates
Branding is organization-scoped JSON. It controls organization display metadata and the invitation email template used for new users.
Routes
| Action | Route | Roles |
|---|---|---|
| Read branding | GET /api/v1/organizations/{id}/branding | CLIENT_ADMIN, PLATFORM_ADMIN |
| Update branding | PUT /api/v1/organizations/{id}/branding | CLIENT_ADMIN, PLATFORM_ADMIN |
Platform admins must pass the target organization ID and tenant scope because a master realm token is not naturally tenant-scoped.
Branding Payload
Example:
{
"branding": {
"app_name": "Example Wipe",
"logo_url": "https://static.example.com/logo.png",
"email_templates": {
"user_invited_subject": "Welcome to {{app_name}}",
"user_invited_text": "You have been invited to {{organization_name}} as {{role}}. Accept: {{accept_url}}",
"user_invited_html": "<html><body><img src=\"{{logo_url}}\" alt=\"{{app_name}} logo\"><p>You have been invited to {{organization_name}} as <strong>{{role}}</strong>.</p><p><a href=\"{{accept_url}}\">Accept invitation</a></p></body></html>"
}
}
}
The admin platform can edit logo_url, app_name, and the
email_templates.* fields. The backend renders the email body from these
templates rather than sending raw JSON.
Template Variables
Supported variables:
| Variable | Meaning |
|---|---|
{{app_name}} | Branding application name or default app name. |
{{logo_url}} | Logo URL to render in HTML templates. |
{{accept_url}} | Absolute invitation acceptance URL. |
{{email}} | Invited user email. |
{{role}} | Invited user role. |
{{organization_name}} | Display name of the organization. |
{{organization_id}} | Organization UUID. |
{{created_by}} | Subject that created the invitation. |
{{expires_at}} | Invitation expiration timestamp. |
URL Security
Branding URLs are validated with the outbound URL policy. The default policy rejects localhost, private network addresses, link-local addresses, multicast addresses, credentials in URLs, and unsupported schemes.
For production, prefer hosting logo assets in controlled object storage or a
known static asset host, then allowlist that host with
SECURITY_OUTBOUND_ALLOWED_HOSTS.
Invitation Host Checklist
Before testing invitations:
| Check | Expected value |
|---|---|
PUBLIC_INVITATION_BASE_URL | Public API origin, for example https://wipe.example. |
| Email HTML | Contains an absolute /api/v1/invitations/accept?... link. |
| Logo | Uses the admin-configured logo_url when present. |
| Mailpit/SMTP | Message body is rendered HTML/text, not JSON payload text. |