Theme

Settings API

The tunable knobs an agent may turn: the named durations flows reference, the send windows that gate when scheduled email goes out, the mailing address email footers show, and unsubscribe flows — page copy, subscription preferences, and the custom redirect. How emails look is a theme, not a setting. Credentials are never here.

Method & pathWhat it does
GET /api/v1/settingsThe writable settings and their current values.
PATCH /api/v1/settingsUpdate any of them. Partial: only the keys you send change. Values are shape-checked before anything is stored.

The writable keys

KeyWhat it is
tunablesNamed durations flows reference by name — { "quiet_buffer_days": { "amount": 40, "unit": "days" } }. Units: minutes, hours, days, weeks.
send_windowsWhen scheduled sends are allowed out. Format below.
sending.mailing_addressThe physical mailing address {{ mailing_address }} resolves to in email footers, as one string. Anti-spam law requires one in every marketing email; a P.O. box works. Stored stripped of surrounding whitespace.
sending.unsubscribe_page_urlA custom URL people are sent to right after Mimeo's unsubscribe page unsubscribes them. Blank (the default) means they stay on Mimeo's page, which offers a resubscribe button. A full http(s) URL sends them on, with the signed token appended as ?token=… or dropped into a {token} placeholder. Anything that isn't a full URL is refused; blank clears it.
sending.subscription_preferencesThe hosted preference configuration object: enabled state, public tab labels, introductory text, save copy, and tag/custom-field toggles. Shape and example below.
sending.unsubscribe_page.introductionText before the global unsubscribe form. Default: {email} will stop getting all email from us. The address is safely substituted in bold, as it is in after-unsubscribe and after-resubscribe confirmation text. Blank restores the default.
sending.unsubscribe_page.status
.headline · .confirmation
.button_text · .button_color · .hint
What Mimeo's page says once someone is unsubscribed: the status line, headline, confirmation text ({email} becomes the person's address), the resubscribe button's text and hex color, and the small text under the button. Each has a default (Done / You're unsubscribed. / {email} won't get any more email from us. / Resubscribe / the design system's accent / Clicked by mistake? This puts you back.); blank restores it. Text is stored stripped; a color that isn't hex is refused.
sending.unsubscribe_page.resubscribed_status
.resubscribed_headline
.resubscribed_confirmation
.resubscribed_button_text
.resubscribed_hint
The same for what the page says after the resubscribe button is pressed. Defaults: Welcome back / You're subscribed again. / {email} will keep getting email from us. / Unsubscribe / Changed your mind again? One click and you're out.

These are the same keys settings.yml carries in a definitions repo — the API, MCP and a repo push all write the same settings through the same checks.

Hosted subscription preferences

Send literal dotted setting keys inside settings. The sending.subscription_preferences object is replaced, not deep-merged with the saved object; omitted properties take defaults. Read the current value first when editing an existing configuration so you preserve its toggles and copy. This example adds a weekly-news preference alongside global unsubscribe:

PATCH /api/v1/settings
Authorization: Bearer mm_your_token
Content-Type: application/json

{
  "settings": {
    "sending.unsubscribe_page_url": "",
    "sending.unsubscribe_page.introduction": "{email} will stop getting all email from us.",
    "sending.subscription_preferences": {
      "enabled": true,
      "unsubscribe_label": "Unsubscribe from everything",
      "preferences_label": "Manage my subscriptions",
      "introduction": "Choose the emails you'd like to receive at {email}.",
      "default_tab": "preferences",
      "save_button_text": "Save preferences",
      "success_message": "Your subscription preferences have been saved.",
      "toggles": [
        {
          "id": "weekly_news",
          "label": "Weekly news",
          "description": "One roundup each week.",
          "condition": { "type": "has_tag", "tag": "weekly_news" },
          "on": [{ "type": "add_tag", "tag": "weekly_news" }],
          "off": [{ "type": "remove_tag", "tag": "weekly_news" }]
        }
      ]
    }
  }
}
Configuration fieldDefault and constraints
enabledBoolean, default false. Enabling requires at least one toggle.
unsubscribe_labelUnsubscribe from everything.
preferences_labelManage my subscriptions.
introductionChoose the emails you'd like to receive at {email}. Shown above preferences; the address is safely substituted in bold.
default_tab"unsubscribe" (default) or "preferences".
save_button_textSave preferences.
success_messageYour subscription preferences have been saved.
togglesArray, default [], up to 30 toggles. The five copy fields above require 1–500 characters, not blank; surrounding whitespace is stripped.
Toggle fieldContract
idUnique, 1–80 characters: letters, digits, underscore or hyphen ([a-zA-Z0-9_-]).
label / descriptionRequired nonblank label, up to 200 characters; optional description, up to 1000 characters.
conditionThe On when rule: has_tag or field, or not, all, any combinations using the flow condition schema. No other condition types. Up to five levels including the root; each all/any has 1–30 children.
on / offRequired action arrays, each with up to 30 actions. The selected branch runs on save for every toggle, even unchanged toggles.

Supported actions:

{ "type": "add_tag", "tag": "weekly_news" }
{ "type": "remove_tag", "tag": "weekly_news" }
{ "type": "set_field", "field": "news_frequency", "value": "weekly" }
{ "type": "clear_field", "field": "news_frequency" }

Field actions require an existing active custom field. A set value must match its type; use clear_field rather than a blank or null set value. A field-based toggle could use this condition, with the set action on and the clear action off:

{
  "type": "field",
  "field": "news_frequency",
  "op": "equals",
  "value": "weekly"
}

Each branch may write a tag or field only once, and two toggles cannot write the same target (tag names are normalized). Actions must make every condition match the submitted selections; otherwise the entire preference save rolls back. Actions change tags and fields, never global suppression.

A nonblank custom unsubscribe URL prevents hosted preferences from being active. The Settings UI clears that URL when enabling preferences, and disables preferences while retaining definitions when saving a custom URL. API callers should write the intended combination explicitly, as above: clear the URL to enable hosted preferences, or send the full saved configuration with enabled: false when choosing a custom URL. To disable without losing definitions, retain toggles and the other fields in the replacement object.

Preferences need sending rules. Use their tags or fields in audiences and segments, and add send-time guards for already queued mail. These are not created automatically. Keep operator API tokens server-side; the hosted subscriber form uses its signed token, not your API credential.

The send-window rule format

PATCH /api/v1/settings
{ "settings": { "send_windows": { "rules": [
  { "label": "pitch", "days": [1, 2, 3, 4], "start": "11:00", "end": "15:00" },
  { "label": null,    "days": [1, 2, 3, 4, 5], "start": "09:00", "end": "17:00" }
] } } }
KeyMeaning
labelScope the rule to emails carrying this label. null, or omitted, makes it the global rule.
daysWeekday numbers, 0–6 with Sunday as 0. Required, and at least one.
start / end"HH:MM" on a 24-hour clock. Omitted, they default to "00:00" and "24:00"; "24:00" closes the day. start must be before end.

Rules are optional and additive: with none configured, everything sends the moment it comes due. Exactly one rule applies to any given email — the first whose label the email carries, else the first global rule. Times are evaluated in the account's timezone (the profile timezone setting, Eastern Time if none is set), so "9–5" means 9–5 on your own clock. An email due outside its window isn't dropped or rushed: it's held with its due time moved to the next open slot, visible in the queue as “Outside its send window”.

Errors

StatusWhen
401Missing or revoked token.
422A key that isn't writable — credentials and secrets are entered on the Settings page and stay in the instance — or a malformed value. The message names the exact problem rather than storing something that would quietly hold sends.

Over MCP, get_settings and save_settings take the same contract, and a settings.yml push through the definitions endpoints runs the same checks — a malformed rule blocks the plan with setting_invalid.

See also: The definitions repo · MCP · The queue, for humans