Skip to content

Reference

alter branding

Read and update an app's branding / theming config.

Branding controls how the Connect widget looks for an app (logo, colors, font). These commands read and update it; the visual editor in the dashboard is usually the easier way to author a theme. Branding does not restyle the Wallet — see Wallet.

alter branding get --app <app-id-or-name>
alter branding set --app <app-id-or-name> --input <@file|-> [--replace]
alter branding reset --app <app-id-or-name> [--yes]

All commands are app-scoped — pass --app <id> (or the app’s name), or link a workspace / set ALTER_APP_ID. get needs dashboard_branding:read; set / reset need dashboard_branding:write. Branding is recoverable config — reset restores Alter defaults, and can be undone by setting it again on a plan that includes custom branding (see below).

Terminal window
alter branding get

Accepts --output <format> (json, jsonl, or table; default json).

Update branding from a JSON body. Two verbs mirror the dashboard’s branding editor:

  • default (PATCH) — a partial merge-update of an existing config; fields you omit are left unchanged. If no branding is configured yet, the command exits 2 (usage) with a hint to re-run with --replace. Note this is not the 4 (NOT_FOUND) the exit-code table lists for a 404: the missing config is a fixable input problem, not an absent resource, so a script branching on 4 to mean “create it” never fires.
  • --replace (PUT) — create or fully replace branding. Use this for initial setup; it requires logo_url plus all three colors (primary, text, background). font_family is optional.

The input is parsed as JSON locally. Any supplied primary, text, or background color must use #RRGGBB. A body that supplies logo_url must also supply all three colors, and a body that supplies all three colors must also supply logo_url; these correlated checks run before the request.

logo_url accepts either an https:// URL to a hosted image (2,048 characters max) or a small inline data:image/{png|jpeg|webp};base64,… image, up to 150,000 characters of data URI (about 110 KB decoded). Accepted inline formats are PNG, JPEG, and WebP; the dashboard’s upload control emits a downscaled PNG. SVG is not accepted inline (a hosted https:// URL may still point at an SVG file).

A hosted https:// URL must carry no embedded credentials (user:pass@, or a bare @ in the authority) and no quotes, angle brackets, backticks, backslashes, whitespace or control characters — percent-encode any of those. It must resolve to a public network address; loopback, link-local, private and reserved destinations are rejected. The CLI applies these rules locally and exits 2 before the request, so a malformed address fails immediately rather than as a server-side 422. font_family takes a CSS font stack whose first name selects the web font to load — a Google Fonts family or a system font; any remaining names are passed through as the fallback stack. Letters, digits, spaces, hyphens, commas and dots only, 200 characters max; quotes are rejected, so write Inter, sans-serif rather than 'Inter', sans-serif. Common Google Fonts names are matched regardless of casing, and fonts are served from Alter’s own origin (no third-party request is made from an end user’s browser).

When logo_url is a hosted https:// address, the save fetches it and reports whether it is actually a displayable image. The verdict comes back on the response as logo_preflight and is printed to stderr, so it survives --output table and piping stdout through jq:

StatusMeaning
passedFetched, and the content type is a displayable image.
failedDemonstrably not displayable — the address serves a web page, or the image is not there. The most common cause is pasting a page URL whose image sits behind a # fragment the server never sees.
inconclusiveCould not be verified — a redirect that is deliberately not followed, a 403 from hotlink protection, or a transient fault.
skippedNo fetch was needed — an uploaded data URI, or a logo that did not change.

Ordinary image verdicts never block the save. A wrong logo makes the page look wrong, and an operator mid-rebrand whose asset is about to be published should not be locked out. failed is reported loudly and the branding is still stored. A private or blocked destination is the exception: it is rejected before the write so a Connect page cannot make an end user’s browser request that user’s network.

set requires a plan that includes custom branding (Starter and above). On a plan without it the command exits 7 (forbidden) and prints the plan requirement. reset is always available, so an organization that downgrades can still clear custom branding it can no longer edit. The dashboard equivalent is documented in Setting up your app.

FlagRequiredDescription
--input <path>yesJSON branding body from a file (@/path/to/branding.json) or stdin (-).
--replacenoCreate or fully replace branding (PUT) instead of merge-updating (PATCH).
--output <format>nojson (default), jsonl, or table.
Terminal window
# First-time setup (create):
alter branding set --replace --input @branding.json
# Later tweak (merge-update an existing config):
alter branding set --input @branding.json

Reset branding to Alter defaults. Reversible on a plan that includes custom branding — re-run set to restore a custom theme. reset itself is available on every plan, so a downgraded organization can always clear branding it can no longer edit.

FlagDefaultDescription
--yesoffSkip the interactive confirmation prompt (for CI).
Terminal window
alter branding reset --yes

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.