Profile Branding
Set the logo, display name, and primary color that render on the UniPost-hosted Connect page. This is how you make the OAuth onboarding flow look like your product instead of UniPost.
Where the fields appear
The hosted Connect page at app.unipost.dev/connect/{platform} reads these three values at render time — there’s no cache layer, so a PATCH is live on the very next page load. See the Hosted Connect guide for the setup model that separates Hosted Connect branding, Platform Credentials, and Connect Sessions.
Plan packaging matters here: Basic and up can brand the hosted Connect page. Basic branding applies only to the workspace's one shared custom platform slot, the same slot used for Platform Credentials. Growth, Team, and Enterprise apply branding across all supported platforms and can hide the Powered by UniPost footer.
| Field | Where it appears on the Connect page |
|---|---|
| branding_logo_url | Top-left mark |
| branding_display_name | Page title + tab name |
| branding_primary_color | Primary button and accent color |
| branding_hide_powered_by | Hides the footer attribution (Growth / Team only) |
Update branding
PATCH is partial — send only the fields you want to change. Each field accepts an empty string to unset (falls back to UniPost defaults).
The dashboard Hosted Connect page uses this endpoint for display name, color, and attribution. Logo files can be uploaded directly from the same dashboard page or through the multipart logo endpoint below.
Upload or remove a logo
Use the logo upload endpoint when you have a local PNG or JPG file and do not want to host it yourself. UniPost stores the asset in R2, writes the returned public URL to branding_logo_url, and keeps the internal storage key private. R2-managed profile branding objects are retained indefinitely; replacing or removing a logo only changes the profile pointer.
| Endpoint | Body | Result |
|---|---|---|
POST/v1/profiles/{id}/branding/logo | multipart/form-data with file | Stores PNG/JPG logo and returns the updated profile |
DELETE/v1/profiles/{id}/branding/logo | No body | Clears the profile logo fields; the R2 object is retained |
Field validation
| Field | Rule | Reason |
|---|---|---|
| branding_logo_url | Set by logo upload, or HTTPS URL when patched directly; direct URL max 512 chars | The Connect page runs on HTTPS; uploaded assets are served from UniPost-managed R2 |
| logo upload file | PNG or JPG; ≤ 2 MB; image width and height each ≤ 4096 px | Keeps hosted Connect lightweight and avoids oversized customer assets |
| branding_display_name | ≤ 60 characters | Keeps the browser title + meta description readable across devices |
| branding_primary_color | 6-digit hex e.g. #10b981 | Matches the color-mix() and other CSS variables in the Connect page stylesheet |
A bad value returns 422 VALIDATION_ERROR with a human-readable message naming the offending field. No partial updates happen on validation failure — the entire PATCH is atomic.
Read current branding
Branding fields come back on the standard profile read endpoint alongside id, name, workspace_id, and timestamps.
Null values mean the field has never been set for this profile and the hosted Connect page will use UniPost’s default appearance for that slot.
Multiple profiles per workspace
Branding is scoped per profile, not per workspace. If your workspace has multiple profiles (e.g., separate brands under one parent company), each profile can carry its own logo / name / color. Connect sessions created against a given profile use that profile’s branding.
Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED / unauthorized | Missing or invalid API key |
| 402 | PLAN_FEATURE_NOT_AVAILABLE / plan_feature_not_available | The workspace plan cannot brand hosted Connect |
| 404 | NOT_FOUND / not_found | Profile does not belong to the caller’s workspace |
| 413 | PAYLOAD_TOO_LARGE / payload_too_large | Logo file is larger than 2 MB |
| 422 | VALIDATION_ERROR / validation_error | A field failed validation (URL scheme, length, or hex format) |
| 503 | STORAGE_NOT_CONFIGURED / storage_not_configured | Logo upload storage is temporarily unavailable |
Public API errors also include a lowercase error.normalized_code alias and a top-level request_id for tracing.