Branding And Email Templates

Branding is organization-scoped JSON. It controls organization display metadata and the invitation email template used for new users.

Routes

ActionRouteRoles
Read brandingGET /api/v1/organizations/{id}/brandingCLIENT_ADMIN, PLATFORM_ADMIN
Update brandingPUT /api/v1/organizations/{id}/brandingCLIENT_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:

VariableMeaning
{{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:

CheckExpected value
PUBLIC_INVITATION_BASE_URLPublic API origin, for example https://wipe.example.
Email HTMLContains an absolute /api/v1/invitations/accept?... link.
LogoUses the admin-configured logo_url when present.
Mailpit/SMTPMessage body is rendered HTML/text, not JSON payload text.