Branding & White-Label
Breeze’s data model supports white-label branding – logo, colors, custom CSS, and a custom domain – at both the partner (MSP) and organization (customer) levels, read by the end-user portal, quotes, and invoices at render time. Settings > Organization and Settings > Partner each have a Branding tab for entering an appearance preference, and Settings > Organization > Portal controls the portal’s feature toggles and support-contact fields.
Overview
Section titled “Overview”Branding is configured at two levels:
- Partner (MSP) – an appearance preference (logo, colors, theme, custom CSS) intended as the default for the partner’s managed organizations.
- Organization (customer) – the same kind of appearance preference, plus the portal’s feature toggles and support-contact fields, which are what customers actually see today (see Organization Branding).
Logo Customization
Section titled “Logo Customization”Breeze currently supports a single logo per organization and per partner (MSP) – there is no separate dark-mode variant or favicon upload today.
Uploading a Logo
Section titled “Uploading a Logo”-
Navigate to Settings > Organization > Branding (or Settings > Partner > Branding to set the MSP-wide default).
-
In the Logo section, upload an image file or paste a hosted image URL.
-
A preview appears immediately in the editor.
-
Click Save to persist the changes.
Color Customization
Section titled “Color Customization”Two brand colors control the visual theme across all branded surfaces:
| Color | Default | Usage |
|---|---|---|
| Primary | #2563eb (blue) |
Dashboard header, portal header background, email header, link colors, primary buttons |
| Secondary | #f97316 (orange) at partner level, #14b8a6 (teal) at org level |
Call-to-action buttons, accent borders, secondary highlights |
Setting Colors
Section titled “Setting Colors”Colors are entered as hex values (3 or 6 digit). The editor provides both a color picker and a text input. Invalid hex values are silently replaced with the default.
- Open Settings > Organization > Branding (or Settings > Partner > Branding).
- Use the color pickers or enter hex codes in the Primary color and Secondary color fields.
- Use the preview panel to see how the colors look before saving.
- Click Save.
Contrast Calculation
Section titled “Contrast Calculation”The branding editor automatically calculates text contrast for each color swatch. Text on colored backgrounds uses white (#f8fafc) for dark colors and dark (#0f172a) for light colors, based on relative luminance:
luminance = (0.299 * R + 0.587 * G + 0.114 * B) / 255text color = luminance > 0.6 ? dark : lightThis ensures buttons and headers remain readable regardless of the chosen brand colors.
Organization Branding
Section titled “Organization Branding”Each organization has its own branding record in the portal_branding table, keyed by orgId (unique constraint). The visual fields below (logo, colors, custom domain, custom CSS) are read by the portal, quotes, and invoices when rendering, but – as noted above – there is currently no admin-facing way to write them. Only the portal feature toggles and support-contact fields (enableTickets, enableAssetCheckout, enableSelfService, enablePasswordReset, supportEmail, supportPhone, welcomeMessage, footerText) can be set today, from Settings > Organization > Portal.
Branding Schema
Section titled “Branding Schema”| Field | Type | Description |
|---|---|---|
logoUrl |
text | URL to the primary logo image |
faviconUrl |
text | URL to the favicon |
primaryColor |
varchar(50) | Primary brand color (hex) |
secondaryColor |
varchar(50) | Secondary brand color (hex) |
accentColor |
varchar(50) | Optional accent color (hex) |
customDomain |
varchar(255) | Custom portal domain (e.g., support.acmecorp.com) |
domainVerified |
boolean | Whether the custom domain’s DNS has been verified |
welcomeMessage |
text | Welcome text displayed on the portal landing page |
supportEmail |
varchar(255) | Support email shown in emails and portal footer |
supportPhone |
varchar(50) | Support phone number |
footerText |
text | Custom footer text for the portal |
customCss |
text | Injected CSS for fine-grained portal styling |
enableTickets |
boolean | Enable the ticket submission feature on the portal |
enableAssetCheckout |
boolean | Enable asset checkout/return on the portal |
enableSelfService |
boolean | Enable self-service tools on the portal |
enablePasswordReset |
boolean | Enable password reset on the portal |
Org Branding Editor
Section titled “Org Branding Editor”Settings > Organization > Branding provides a simplified appearance editor compared to the partner-level one. It includes:
- Logo upload – single logo (preview-only today; see the caution above)
- Primary and secondary color pickers
- Theme selector –
light,dark, orsystem(respects OS preference) - Portal subdomain – configures the
<subdomain>.breeze.appURL field - Custom CSS – advanced styling overrides
- Live preview – modal showing how the portal will look with current settings
Partner Branding
Section titled “Partner Branding”Partners (MSPs) set an appearance preference – logo, colors, theme, and custom CSS – intended as the default for organizations under their management from Settings > Partner > Branding.
Partner Branding Editor
Section titled “Partner Branding Editor”The partner-level editor provides:
- Logo – upload an image (stored inline, capped at roughly 400 KB) or paste a hosted image URL
- Primary and secondary colors
- Theme –
light,dark, orsystem - Custom CSS
Custom Domains
Section titled “Custom Domains”Custom portal domains (e.g., support.acmecorp.com) are not configurable yet – there is no admin control or API to set or DNS-verify a domain today. The underlying data model supports it (a domain only resolves branding once domainVerified is true), but that work hasn’t shipped.
Supported Assets
Section titled “Supported Assets”Image Formats
Section titled “Image Formats”| Format | Notes |
|---|---|
| SVG | Preferred for logos – scales to any size without pixelation |
| PNG | Use transparent backgrounds for best results |
| JPEG | Supported but not recommended – no transparency support |
Size Recommendations
Section titled “Size Recommendations”| Asset | Minimum | Recommended | Maximum |
|---|---|---|---|
| Logo | 64 x 64 px | 512 x 512 px | Uploaded images are resized client-side to a 256 px box before saving (partner-level editor) |
Custom CSS
Section titled “Custom CSS”Custom CSS is injected after the base stylesheet. Use it for fine-grained control over portal appearance:
/* Adjust portal header spacing */.portal-header { letter-spacing: 0.04em;}
/* Round card corners */.portal-card { border-radius: 18px;}
/* Custom font */body { font-family: 'Inter', system-ui, sans-serif;}API Reference
Section titled “API Reference”Organization Portal Settings
Section titled “Organization Portal Settings”| Method | Path | Description |
|---|---|---|
| GET | /organizations/:id/portal-settings |
Get the portal feature toggles and support-contact fields for an organization |
| PATCH | /organizations/:id/portal-settings |
Update the portal feature toggles and support-contact fields |
Portal Branding
Section titled “Portal Branding”| Method | Path | Description |
|---|---|---|
| GET | /portal/branding/:domain |
Public. Resolve branding by verified custom domain |
| GET | /portal/branding |
Requires an authenticated portal session. Resolves branding for the logged-in user’s own organization |
Request / Response Examples
Section titled “Request / Response Examples”Get portal settings:
GET /organizations/:id/portal-settingsAuthorization: Bearer <token>Response (200):
{ "data": { "orgId": "uuid", "enableTickets": true, "enableAssetCheckout": false, "enableSelfService": true, "enablePasswordReset": true, "supportEmail": "it@acmecorp.com", "supportPhone": "+1-555-0123", "welcomeMessage": "Welcome to Acme IT Support", "footerText": "Powered by Acme IT" }}Update portal settings:
PATCH /organizations/:id/portal-settingsContent-Type: application/jsonAuthorization: Bearer <token>
{ "supportEmail": "it@acmecorp.com", "welcomeMessage": "Welcome to Acme IT Support"}Resolve portal branding by domain:
GET /portal/branding/support.acmecorp.comResponse (200):
{ "branding": { "id": "uuid", "orgId": "uuid", "logoUrl": "https://storage.breeze.app/branding/acme/logo-light.png", "faviconUrl": "https://storage.breeze.app/branding/acme/favicon.ico", "primaryColor": "#1e40af", "secondaryColor": "#f59e0b", "accentColor": null, "customDomain": "support.acmecorp.com", "domainVerified": true, "welcomeMessage": "Welcome to Acme IT Support", "supportEmail": "it@acmecorp.com", "supportPhone": "+1-555-0123", "footerText": "Powered by Acme IT", "customCss": ".portal-header { letter-spacing: 0.04em; }", "enableTickets": true, "enableAssetCheckout": true, "enableSelfService": true, "enablePasswordReset": true }}Troubleshooting
Section titled “Troubleshooting”Logo doesn’t show up on the customer portal, quotes, or invoices. This is expected today – see the caution near the top of this page. Neither the organization nor the partner branding editor currently writes the logo that the portal, quotes, and invoices render.
Live preview does not match saved branding. The live preview reflects unsaved changes in the editor. Confirm the save operation completed (check for the “Branding settings saved” confirmation). Note that a saved appearance preference does not currently change what end users see on the portal itself – see the caution near the top of this page.
“Failed to fetch branding” error in the editor.
This typically indicates an authentication issue. The editor calls GET /organizations/:id/portal-settings (organization level) with the user’s session token. If the token has expired, the editor redirects to the login page. Ensure the user has the organization:write permission.