Update Portal Branding
PUT/api/admin/portal/branding
Update the portal's brand colours, display name and support email. The logo and mark are uploaded separately (Upload Branding Image).
This endpoint currently requires session authentication; Personal Access Token scope support is in progress.
Body fields (all optional; an omitted key is left unchanged, null or a blank string resets it to the SKU default):
- primary_color (string or null): brand colour as a 6-digit hex code, e.g.
#1F3A2E. Used for buttons, links, chips and focus rings. Stored uppercase. - nav_color (string or null): navigation bar colour as a 6-digit hex code, e.g.
#0B0F0C. - display_name (string or null, max 80): the name shown in the portal header, emails and sign-in pages. Null falls back to the default store's company name.
- support_email (string or null, valid email, max 255): the contact address shown to buyers. Stored lowercase.
The save MERGES into the stored branding (the logo and mark are never touched) and bumps version. A low-contrast colour is saved and reported in warnings rather than refused.
Response (data): logo_url, mark_url (null when none uploaded), display_name (the merchant's chosen name, else the default store's company name / store name, else the app name), display_name_is_default (true when no name was set), primary_color, nav_color (uppercase #RRGGBB; SKU defaults #0096DD / #1F2937 when unset), on_primary_color, on_nav_color (the readable text colour for each: #FFFFFF or #111827, whichever contrasts more; the unbranded defaults keep white text), primary_contrast, nav_contrast (WCAG 2.x contrast ratio of that text colour, one decimal, rounded down), support_email, version (bumped on every branding write; append it to image URLs to bust caches) and warnings (array of {field, code, ratio, message}). Warning codes: low_contrast (a merchant-chosen colour where even the better text colour is under 4.5:1) and low_contrast_on_page (a primary colour under 3:1 against the white page, since links, chips and focus rings use it). Warnings never block a save.
Requires a staff bearer token with the portal.manage permission.
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Unprocessable Content
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.