Branding & Customization
The Admin Portal reflects each account's logo and brand color — but today only the vendor side can set them.
What's stored
Branding is two nullable columns on the Account model: logo (a URL string) and brandColor (mapped to brand_color). Both are optional — an account with neither set falls back to portal defaults.
| Field | Type | Validated as |
|---|---|---|
| logo | string, nullable | a URL (zod .url()) |
| brandColor | string, nullable | a 6-digit hex color, e.g. #4f46e5 (zod regex /^#[0-9a-fA-F]{6}$/) |
Where they come from
These fields are set through the vendor-authenticated Accounts API, not through the Admin Portal itself:
/api/v1/accounts/api/v1/accounts/:idBoth accept optional logo and brandColor fields alongside name, slug, and domain.
No self-service branding UI yet
Neither the vendor dashboard nor the Admin Portal currently ships a form for editing logo/brandColor — the fields exist on the model and the update endpoint accepts them, but setting them today means calling the Accounts API directly. The Admin Portal only ever reads and displays these values; a customer IT admin has no way to change their own branding from /portal.
How the portal applies them
When a customer admin's session is verified, GET /api/v1/admin-portal/session returns account.logo and account.brandColor alongside the account's name and slug. The portal layout (/portal) uses them directly:
- If
logois set, it's rendered as an<img>in the header. - Otherwise, a colored square shows the account's first initial, with
backgroundColorset tobrandColor— falling back to#4f46e5when neither is set. - The Settings tab (
/portal/settings) also echoes the brand color as a labeled swatch for the admin to confirm it's correct.
There is no theming beyond this: no custom CSS, no font, no favicon, and no whitelabeling of the portal's own chrome or copy — "branding" here means exactly the logo image and one accent color. For the fuller session payload this comes from, see Magic Link Authentication.