---
title: "Settings"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://openemail.uk/docs/api/reference/settings"
area: "API"
category: "Reference"
---

# Settings

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

Mailbox preferences, the signature and tracking of each address, and the brand of the workspace: its images, fonts and sign-in background.

### `GET /branding`

Retrieve the brand

The brand of the workspace, as its Customisations page shows it: a link to each brand image, the primary and secondary fonts, and the background of the sign-in page.

The mark shows in the app's workspace switcher. The logo shows at the top of the sidebar, and it is what brands the web app address, `GET /app-host`, and, on a paid plan, the emails OpenEmail sends for the workspace, which carry it at the top and the foot. Without a logo, the web app address and the emails look like OpenEmail. The fonts apply in the web app for everyone in the workspace, the primary font to its text and the secondary font to page headings, and the sign-in background shows on the web app address, either way.

A personal space carries no brand, so its images and fonts read as null and `editable` is false.

Requires the `settings:read` scope.

- Scopes: `settings:read`.

**Returns**

- `200` `Branding`: The brand of the workspace.

**Errors**

- The errors every operation can return: `400`, `401`, `403`, `404`, `422`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`branding.get()`](https://openemail.uk/docs/sdk/reference/branding#get); CLI [`openemail branding get`](https://openemail.uk/docs/cli/reference/branding#branding-get); MCP [`getBranding`](https://openemail.uk/docs/mcp/tools/domains#getBranding).

### `PATCH /branding`

Change the fonts and the sign-in background

Changes the fonts, the sign-in page background or both, and returns the brand in the same shape as `GET /branding`. A field left out keeps its value, and so does a font left out of `fonts`. `loginBackground` replaces the background there was, and null sets the default.

With `kind: "image"` the sign-in page shows the photo uploaded with `PUT /branding/images/login-background`, so upload that first: without it the call is refused. Uploading one switches the page to it on its own.

The brand applies to the whole workspace, so a key or app limited to particular addresses or domains cannot change it.

Requires the `settings:write` scope.

- Scopes: `settings:write`.

**Request body**

- `fonts` (`object`): The fonts to change. A font left out keeps its value, and null sets the default.
  - `primary` (`string`, nullable, one of `"system"`, `"arial"`, `"helvetica"`, `"verdana"`, `"tahoma"`, `"trebuchet-ms"`, `"georgia"`, `"times-new-roman"`, `"courier-new"`, `"dm-sans"`, `"inter"`, `"roboto"`, `"open-sans"`, `"lato"`, `"montserrat"`, `"poppins"`, `"nunito"`, `"work-sans"`, `"source-sans-3"`, `"ibm-plex-sans"`, `"merriweather"`, `"playfair-display"`, `"instrument-serif"`, `"jetbrains-mono"`, `"dm-mono"`, `"geist-mono"`): The primary font, or null for the default.
  - `secondary` (`string`, nullable, one of `"system"`, `"arial"`, `"helvetica"`, `"verdana"`, `"tahoma"`, `"trebuchet-ms"`, `"georgia"`, `"times-new-roman"`, `"courier-new"`, `"dm-sans"`, `"inter"`, `"roboto"`, `"open-sans"`, `"lato"`, `"montserrat"`, `"poppins"`, `"nunito"`, `"work-sans"`, `"source-sans-3"`, `"ibm-plex-sans"`, `"merriweather"`, `"playfair-display"`, `"instrument-serif"`, `"jetbrains-mono"`, `"dm-mono"`, `"geist-mono"`): The secondary font, or null for the default.
- `loginBackground` (`object`, nullable): The sign-in page background, replacing the one there was, or null for the default.
  - `kind` (`string`, required, one of `"preset"`, `"color"`, `"image"`): `preset` shows `preset`, `color` fills it with `color`, and `image` shows the image uploaded with `PUT /branding/images/login-background`. `image` is refused with 422 `invalid_parameter` until that image is uploaded, and once it is removed the background falls back to the `preset` or `color` kept with it, or to null.
  - `preset` (`string`, nullable, one of `"dusk"`, `"mist"`, `"sand"`, `"night"`): One of the built-in backgrounds. Required when `kind` is `preset`.
  - `color` (`string`, nullable, pattern `^#[0-9a-f]{6}$`): A colour as `#` and six hex digits, such as `#1f2937`, stored lowercased. Required when `kind` is `color`.
  - `logo` (`string`, nullable, one of `"dark"`, `"light"`): Which logo the sign-in page shows: `dark`, your logo, or `light`, your logo for dark mode (OpenEmail's white logo when you have none). Null picks the one that stands out against the background, and it goes back to null whenever the background changes.

**Returns**

- `200` `Branding`: The brand as this call left it.

**Errors**

- `400`: `malformed_json`: the body is not valid JSON.
- `403`: `insufficient_scope`: the key lacks `settings:write`.
- `409`: `branding_unavailable`: the workspace is a personal space, which carries no brand.
- `422`: `invalid_parameter` naming the field, such as `fonts.primary` for a font that is not on the list, `loginBackground.preset` when `kind` is `preset` and no preset is given, `loginBackground.kind` when `kind` is `image` and no sign-in photo is uploaded, or `loginBackground.color` for a colour that is not `#` and six hex digits. `unknown_parameter` for any other field, and `capability_unsupported` with `param: "domainAllowlist"` for a key or app limited to particular addresses or domains.
- The errors every operation can return: `401`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`branding.update()`](https://openemail.uk/docs/sdk/reference/branding#update); CLI [`openemail branding update`](https://openemail.uk/docs/cli/reference/branding#branding-update); MCP [`updateBranding`](https://openemail.uk/docs/mcp/tools/domains#updateBranding).

### `PUT /branding/images/{variant}`

Upload a brand image

Uploads one brand image, replacing the one there was, and returns the brand. Send the image itself as the body, not JSON, with its type in `Content-Type`. Up to 5 MB goes in. `variant` names the image:

- `mark`: the square mark. `image/svg+xml`, `image/png`, `image/jpeg`, `image/webp`, fitted into 512 by 512 pixels and stored as WebP.
- `wordmark`: the logo. `image/svg+xml`, `image/png`, `image/jpeg`, `image/webp`, fitted into 1024 by 256 pixels and stored as WebP.
- `wordmark-dark`: the logo for dark mode, shown in place of the logo when the app is dark. `image/svg+xml`, `image/png`, `image/jpeg`, `image/webp`, fitted into 1024 by 256 pixels and stored as WebP.
- `login-background`: the photo behind the sign-in page of the web app address. `image/png`, `image/jpeg`, `image/webp`, `image/gif`, fitted into 2560 by 1600 pixels and stored as WebP. Uploading it also switches the sign-in page to it.

An SVG is turned into a picture, and an animated image keeps its first frame.

The brand applies to the whole workspace, so a key or app limited to particular addresses or domains cannot change it.

Requires the `settings:write` scope.

- Scopes: `settings:write`.

**Path parameters**

- `variant` (`string`, required, one of `"mark"`, `"wordmark"`, `"wordmark-dark"`, `"login-background"`): Which image: `mark`, the square icon, `wordmark`, the logo, `wordmark-dark`, the logo for dark mode, or `login-background`, the photo behind the sign-in page.

**Request body**

Content type: `image/webp`, `image/png`, `image/jpeg`, `image/gif`, `image/svg+xml`.

`binary`

**Returns**

- `200` `Branding`: The brand, with the new image.

**Errors**

- `403`: `insufficient_scope`: the key lacks `settings:write`.
- `409`: `branding_unavailable`: the workspace is a personal space, which carries no brand.
- `422`: `invalid_image` when the body is not an image of a type that variant accepts, is too large or cannot be read. `invalid_parameter` on `variant` for a name that is not one of the four, and `capability_unsupported` with `param: "domainAllowlist"` for a key or app limited to particular addresses or domains.
- `502`: `image_not_stored`: the image was read but could not be stored. Try again.
- `503`: `image_busy`: the image service is saturated. Try again shortly.
- The errors every operation can return: `400`, `401`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`branding.uploadImage()`](https://openemail.uk/docs/sdk/reference/branding#uploadImage); CLI [`openemail branding upload-image`](https://openemail.uk/docs/cli/reference/branding#branding-upload-image); MCP [`setBrandImage`](https://openemail.uk/docs/mcp/tools/domains#setBrandImage).

### `DELETE /branding/images/{variant}`

Remove a brand image

Removes one brand image, deletes the stored file and returns the brand, so the default shows in its place. Removing the sign-in photo while the sign-in page shows it switches the page back to the preset or colour chosen before it, or to the default. Removing an image that is not set changes nothing, so a repeated call is safe.

The brand applies to the whole workspace, so a key or app limited to particular addresses or domains cannot change it.

Requires the `settings:write` scope.

- Scopes: `settings:write`.

**Path parameters**

- `variant` (`string`, required, one of `"mark"`, `"wordmark"`, `"wordmark-dark"`, `"login-background"`): Which image: `mark`, the square icon, `wordmark`, the logo, `wordmark-dark`, the logo for dark mode, or `login-background`, the photo behind the sign-in page.

**Returns**

- `200` `Branding`: The brand, without that image.

**Errors**

- `403`: `insufficient_scope`: the key lacks `settings:write`.
- `409`: `branding_unavailable`: the workspace is a personal space, which carries no brand.
- `422`: `invalid_parameter` on `variant` for a name that is not one of the four, and `capability_unsupported` with `param: "domainAllowlist"` for a key or app limited to particular addresses or domains.
- The errors every operation can return: `400`, `401`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`branding.removeImage()`](https://openemail.uk/docs/sdk/reference/branding#removeImage); CLI [`openemail branding remove-image`](https://openemail.uk/docs/cli/reference/branding#branding-remove-image); MCP [`removeBrandImage`](https://openemail.uk/docs/mcp/tools/domains#removeBrandImage).

### `GET /settings`

Read mailbox settings

Every field with defaults filled in, so reading a setting never requires knowing which release introduced it.

`signature`, `openEmailSignature`, `trackOpens` and `trackClicks` belong to each address. There is no workspace-wide or account value for them. Pass `address` to read them the way a send from that address resolves them: the address's own values, then its domain's catch-all when the catch-all caught that address rather than it being one you created, then the built-in defaults. A plus address with no settings of its own reads its base address's. Without `address` the four read as the built-in defaults: no signature, the OpenEmail footer on, and open and link tracking on. Every other field is the workspace's and reads the same either way. `address` in the response is the address the four were resolved for, lowercased, or null.

Requires the `settings:read` scope.

- Scopes: `settings:read`.

**Query parameters**

- `address` (`string`, up to 320 characters): The address whose `signature`, `openEmailSignature`, `trackOpens` and `trackClicks` to read or change, such as `hello@example.com`, or `*@example.com` for the catch-all of that domain. On a read any address resolves the way a send from it would. On a write it has to be an address in this workspace, or a catch-all on a verified domain here with its catch-all on. A key narrowed to particular addresses or domains may name only an address it holds, and a catch-all only on a domain it holds whole, or it is 422 `capability_unsupported`.

**Returns**

- `200`: Settings.

**Errors**

- `422`: `invalid_parameter` on `address` when it is not one address or `*@domain`, or `capability_unsupported` when a narrowed key names an address it does not hold.
- The errors every operation can return: `400`, `401`, `403`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`settings.get()`](https://openemail.uk/docs/sdk/reference/settings#get); CLI [`openemail settings get`](https://openemail.uk/docs/cli/reference/settings#settings-get); MCP [`getSettings`](https://openemail.uk/docs/mcp/tools/workspace#getSettings).

### `PATCH /settings`

Change mailbox settings

A partial update: a field you omit keeps its value.

Without `address`, this changes the workspace's settings. `signature`, `openEmailSignature`, `trackOpens` and `trackClicks` are refused there with 422 `address_required` naming the field, because they are set on each address, and nothing is written. The privacy fields (`externalImages`, `trustedSenders`, `blockedSenders`, `blockedDomains`, `blockedWords`, `useDefaultBlockedWords`) are saved on the workspace and the rest on the workspace owner's account.

With `address`, the body may carry those four fields only, and any other field is 422 `not_per_address` naming it. The address has to be one in this workspace, or `*@domain` for a verified domain here with its catch-all on, or it is 422 `invalid_parameter` on `address`. The values are saved on that address alone and the response is what `GET /settings?address=` returns for it. A catch-all's values apply to the addresses its domain catches, and a new address created on that domain starts with a copy of them and changes on its own from then on.

Returns the SAVED state, so the signature you get back is the sanitised one that will actually be sent rather than what you asked for.

Requires the `settings:write` scope.

- Scopes: `settings:write`.

**Query parameters**

- `address` (`string`, up to 320 characters): The address whose `signature`, `openEmailSignature`, `trackOpens` and `trackClicks` to read or change, such as `hello@example.com`, or `*@example.com` for the catch-all of that domain. On a read any address resolves the way a send from it would. On a write it has to be an address in this workspace, or a catch-all on a verified domain here with its catch-all on. A key narrowed to particular addresses or domains may name only an address it holds, and a catch-all only on a domain it holds whole, or it is 422 `capability_unsupported`.

**Request body**

- `signature` (`string`): HTML signature of the address named by `address`, at most 150,000 characters before and after sanitising. Sanitised on write. An empty string removes it. Only with `address`.
- `openEmailSignature` (`boolean`): Adds the OpenEmail footer to mail from the address named by `address` while it has no signature. On by default. Only with `address`.
- `timezone` (`string`): IANA zone name, saved as given without checking it.
- `language` (`string`): Language code such as `en`, saved as given without checking it.
- `defaultEmailAlias` (`string`): Address the app composer preselects as From.
- `trackOpens` (`boolean`): Open tracking on mail from the address named by `address`, for a send that does not set `tracking.opens`. On by default. Only with `address`.
- `trackClicks` (`boolean`): Link tracking on mail from the address named by `address`, for a send that does not set `tracking.clicks`. On by default. Only with `address`.

**Returns**

- `200`: The saved settings.

**Errors**

- `422`: Rejected: `address_required` (a per-address field sent without `address`), `not_per_address` (a field other than the four sent with `address`), `signature_too_long`, `invalid_parameter`, or `capability_unsupported` when a narrowed key names an address it does not hold.
- The errors every operation can return: `400`, `401`, `403`, `404`, `500`, described in the [error catalog](https://openemail.uk/docs/api/errors).

Also available in: SDK [`settings.update()`](https://openemail.uk/docs/sdk/reference/settings#update); CLI [`openemail settings update`](https://openemail.uk/docs/cli/reference/settings#settings-update); MCP [`updateSettings`](https://openemail.uk/docs/mcp/tools/workspace#updateSettings).

### Objects

#### `Branding`

`object`

The brand of the workspace: its images, its fonts and the background of its sign-in page. The logo is what brands the web app address, `GET /app-host`, and, on a paid plan, the emails OpenEmail sends for the workspace; without one both look like OpenEmail. The fonts apply in the web app for everyone in the workspace, the primary font to its text and the secondary font to page headings, and the sign-in background shows on the web app address, whether or not a logo is set. A personal space carries no brand, so every image and font is null there.

- `object` (`string`, one of `"branding"`)
- `editable` (`boolean`): Whether this key may change the brand: false in a personal space, without `settings:write`, or for a key limited to particular addresses or domains.
- `images` (`object`): A link to each brand image, or null when it is not set.
  - `mark` (`string`, nullable): The square mark, or null.
  - `wordmark` (`string`, nullable): The logo, or null.
  - `wordmarkDark` (`string`, nullable): The logo for dark mode, or null. Without it the logo shows in dark mode too.
  - `loginBackground` (`string`, nullable): The photo behind the sign-in page, or null.
- `fonts` (`object`): The two fonts of the brand, each a font id from the supported list or null for the default.
  - `primary` (`string`, nullable, one of `"system"`, `"arial"`, `"helvetica"`, `"verdana"`, `"tahoma"`, `"trebuchet-ms"`, `"georgia"`, `"times-new-roman"`, `"courier-new"`, `"dm-sans"`, `"inter"`, `"roboto"`, `"open-sans"`, `"lato"`, `"montserrat"`, `"poppins"`, `"nunito"`, `"work-sans"`, `"source-sans-3"`, `"ibm-plex-sans"`, `"merriweather"`, `"playfair-display"`, `"instrument-serif"`, `"jetbrains-mono"`, `"dm-mono"`, `"geist-mono"`): The primary font, or null for the default.
  - `secondary` (`string`, nullable, one of `"system"`, `"arial"`, `"helvetica"`, `"verdana"`, `"tahoma"`, `"trebuchet-ms"`, `"georgia"`, `"times-new-roman"`, `"courier-new"`, `"dm-sans"`, `"inter"`, `"roboto"`, `"open-sans"`, `"lato"`, `"montserrat"`, `"poppins"`, `"nunito"`, `"work-sans"`, `"source-sans-3"`, `"ibm-plex-sans"`, `"merriweather"`, `"playfair-display"`, `"instrument-serif"`, `"jetbrains-mono"`, `"dm-mono"`, `"geist-mono"`): The secondary font, or null for the default.
- `loginBackground` (`object`, nullable): What the sign-in page of the web app address shows behind the form, or null for the default. `kind` picks one of three: a `preset`, a `color` or the uploaded `image`. The value for the other kinds may be kept, so switching back restores it.
  - `kind` (`string`, required, one of `"preset"`, `"color"`, `"image"`): `preset` shows `preset`, `color` fills it with `color`, and `image` shows the image uploaded with `PUT /branding/images/login-background`. `image` is refused with 422 `invalid_parameter` until that image is uploaded, and once it is removed the background falls back to the `preset` or `color` kept with it, or to null.
  - `preset` (`string`, nullable, one of `"dusk"`, `"mist"`, `"sand"`, `"night"`): One of the built-in backgrounds. Required when `kind` is `preset`.
  - `color` (`string`, nullable, pattern `^#[0-9a-f]{6}$`): A colour as `#` and six hex digits, such as `#1f2937`, stored lowercased. Required when `kind` is `color`.
  - `logo` (`string`, nullable, one of `"dark"`, `"light"`): Which logo the sign-in page shows: `dark`, your logo, or `light`, your logo for dark mode (OpenEmail's white logo when you have none). Null picks the one that stands out against the background, and it goes back to null whenever the background changes.
