Theme Configuration
The TenantBrandingController at /api/v1/tenants/{tenantId}/branding manages all visual customization including colors, logos, typography, custom CSS, login page branding, and email templates.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /branding | Get current branding configuration |
GET | /branding/render | Get rendered branding (with dark mode support) |
POST | /branding/initialize | Initialize branding with defaults |
PUT | /branding | Update full branding configuration |
PUT | /branding/logo | Update logo configuration |
PUT | /branding/colors | Update color scheme |
GET | /branding/presets | List available theme presets |
POST | /branding/presets/{presetName} | Apply a theme preset |
PUT | /branding/custom-css | Update custom CSS |
PUT | /branding/login-page | Update login page customization |
PUT | /branding/email | Update email branding |
POST | /branding/reset | Reset to platform defaults |
Initializing Branding
When a tenant is first provisioned, branding is initialized with platform defaults:
curl -X POST http://localhost:8082/api/v1/tenants/{tenantId}/branding/initialize \
-H "Authorization: Bearer $TOKEN"Response (201 Created): Returns the TenantBranding entity with default values.
Getting Branding Configuration
Raw Configuration
curl http://localhost:8082/api/v1/tenants/{tenantId}/branding \
-H "Authorization: Bearer $TOKEN"Rendered Branding (with Dark Mode)
curl "http://localhost:8082/api/v1/tenants/{tenantId}/branding/render?darkMode=true" \
-H "Authorization: Bearer $TOKEN"The rendered endpoint returns a BrandingResponse that resolves the appropriate color scheme based on the darkMode parameter.
Updating Colors
curl -X PUT http://localhost:8082/api/v1/tenants/{tenantId}/branding/colors \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-User-Id: {userId}" \
-d '{
"primaryColor": "#1a73e8",
"secondaryColor": "#5f6368",
"accentColor": "#fbbc04",
"backgroundColor": "#ffffff",
"textColor": "#202124",
"sidebarColor": "#f8f9fa",
"headerColor": "#1a73e8"
}'The X-User-Id header is used for audit trail tracking to record who made the change.
Updating Logo
curl -X PUT http://localhost:8082/api/v1/tenants/{tenantId}/branding/logo \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-User-Id: {userId}" \
-d '{
"logoUrl": "https://cdn.acmecorp.com/logo.svg",
"logoDarkUrl": "https://cdn.acmecorp.com/logo-dark.svg",
"faviconUrl": "https://cdn.acmecorp.com/favicon.ico",
"logoWidth": 180,
"logoHeight": 40
}'Theme Presets
List Available Presets
curl http://localhost:8082/api/v1/tenants/{tenantId}/branding/presets \
-H "Authorization: Bearer $TOKEN"Returns a list of ThemePresetInfo objects with preview colors and descriptions.
Apply a Preset
curl -X POST http://localhost:8082/api/v1/tenants/{tenantId}/branding/presets/corporate-blue \
-H "Authorization: Bearer $TOKEN" \
-H "X-User-Id: {userId}"Applying a preset overwrites the current color scheme and typography settings but preserves logos and custom CSS.
Custom CSS
@Data
public static class CustomCssRequest {
private String css;
private boolean enabled;
}curl -X PUT http://localhost:8082/api/v1/tenants/{tenantId}/branding/custom-css \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-User-Id: {userId}" \
-d '{
"css": ".sidebar { border-radius: 8px; } .header { box-shadow: 0 2px 4px rgba(0,0,0,0.1); }",
"enabled": true
}'Custom CSS is sanitized server-side to prevent XSS attacks. The enabled flag allows disabling custom CSS without deleting it.
Login Page Customization
curl -X PUT http://localhost:8082/api/v1/tenants/{tenantId}/branding/login-page \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-User-Id: {userId}" \
-d '{
"backgroundImageUrl": "https://cdn.acmecorp.com/login-bg.jpg",
"welcomeText": "Welcome to Acme Analytics",
"footerText": "Powered by MATIH Platform",
"showPoweredBy": false,
"customHtml": "<div class=\"announcement\">System maintenance scheduled for Sunday</div>"
}'Email Branding
Configure the branding for all outgoing emails (notifications, invitations, reports):
curl -X PUT http://localhost:8082/api/v1/tenants/{tenantId}/branding/email \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-User-Id: {userId}" \
-d '{
"headerColor": "#1a73e8",
"footerColor": "#f8f9fa",
"logoUrl": "https://cdn.acmecorp.com/email-logo.png",
"fromName": "Acme Analytics",
"replyTo": "support@acmecorp.com",
"footerHtml": "<p>Acme Corp | 123 Main St | Unsubscribe</p>"
}'Reset to Defaults
Reset all branding to platform defaults:
curl -X POST http://localhost:8082/api/v1/tenants/{tenantId}/branding/reset \
-H "Authorization: Bearer $TOKEN" \
-H "X-User-Id: {userId}"Returns 204 No Content. This action is irreversible.
Source Files
| File | Path |
|---|---|
| Controller | control-plane/tenant-service/src/main/java/com/matih/tenant/controller/TenantBrandingController.java |
| Service | control-plane/tenant-service/src/main/java/com/matih/tenant/service/TenantBrandingService.java |
| Entity | control-plane/tenant-service/src/main/java/com/matih/tenant/entity/TenantBranding.java |