Skip to content

Settings reference

Generated from contracts/settings.schema.json by node docs/gen.mjs. Do not edit by hand.

One JSON document per app. Read and write it in the dashboard (Settings) or with GET and PUT /v1/app/settings (see the settings overview). Every key has a default, so {} is valid. Unknown keys are refused. A PUT replaces the whole document and needs If-Match with the current version.

Cross-field rules: role keys are unique; every role named in default_role, guests.role, policy, limits, onboarding.slides and calls.per_minute.payer_role exists in roles; each from/to pair appears once in policy; i18n.default_lang is one of i18n.languages. The settings overview explains them.

Key Type Default Meaning
default_role role key "member" Role when the token has none.
version 1 1 Settings schema version.

Look of the chat.

How the chat looks. The colours, the font and the corner radius apply everywhere the chat shows.

Primary is the colour of buttons, and on_primary is the text drawn on it, so pick a pair with enough contrast. Background, surface and text colour the chat’s page, its cards and its words. A web font needs font_css_url, the stylesheet that defines it.

Key Type Default Meaning
branding.avatars boolean true Show the people’s pictures; off draws the initial on the primary colour.
branding.background color #rrggbb "#ffffff" Background color.
branding.font_css_url https URL or null null Stylesheet that loads the font.
branding.font_family string, up to 200 chars "system-ui, sans-serif" CSS font family.
branding.heading_font_family string, up to 200 chars or null null CSS font family for headings; null uses font_family.
branding.inbox_close_chip boolean false The inbox close button is a 30px tinted chip.
branding.inbox_tint boolean false Tint the inbox background on every layout, not only two-pane.
branding.launcher.enabled boolean true Show the launcher bubble.
branding.launcher.inline_close_desktop boolean true Show the inbox close button on the inline page on a screen with a mouse.
branding.launcher.plain boolean false Flat bubble colour, and Arial in the unread badge and the toast.
branding.launcher.position "right", "left" "right" Launcher corner.
branding.logo_url https URL or null null Logo image.
branding.on_primary color #rrggbb "#ffffff" Text on the primary color.
branding.primary color #rrggbb "#2f6fed" Primary color.
branding.radius_px integer, 0 to 32 12 Corner radius in pixels.
branding.surface color #rrggbb "#f4f5f7" Surface color.
branding.text color #rrggbb "#111318" Text color.

Video calls.

Key Type Default Meaning
calls.area string ^[A-Z_]{2,32}$ "GLOBAL" Agora area code, e.g. EUROPE.
calls.codec "vp8", "vp9", "h264", "av1" "vp8" Agora video codec.
calls.confirm_start boolean false Ask before starting a call.
calls.dock boolean false Every call takes the whole window, the chat button docks the call as a strip or a side rail beside the thread, and a minimise button shrinks it to a bubble.
calls.enabled boolean false Video calls enabled.
calls.max_duration_minutes integer, 1 to 1440 240 Calls end after this.
calls.offline_note boolean false After calling an offline peer, note in the thread that they may not answer.
calls.per_minute.currency ISO 4217 code "EUR" ISO 4217 currency.
calls.per_minute.enabled boolean false Charge calls per minute.
calls.per_minute.payer_role role key or null null Role that pays; null is the caller.
calls.per_minute.preauthorize_minutes integer, 1 to 60 1 Minutes charged when both have joined.
calls.per_minute.price_minor integer, at least 0 0 Price per minute in minor units.
calls.ring_timeout_seconds integer, 10 to 600 45 Ring time before missed.
calls.ring_when_closed boolean true An incoming call opens the chat and rings while it is closed; off shows the toast and sound, and the ring when the chat opens.
calls.show_locked boolean false Show buyers a locked call button with a tip when they cannot call a seller.
calls.single_card boolean false One card per call that reads Call ended when it is over, and a busy callee closes the caller’s call screen instead of showing an error.
calls.video.fps integer, 1 to 60 30 Capture frame rate.
calls.video.height integer, 120 to 2160 720 Capture height in pixels.
calls.video.width integer, 160 to 3840 1280 Capture width in pixels.
calls.warn_if_offline boolean true Warn before calling an offline peer.

Messages.

Key Type Default Meaning
chat.avatar_upload boolean false Users may upload their own picture; it shows only after photo moderation approves it, and it wins over the host’s avatar.
chat.consent_allow_last boolean false The photo consent prompt puts Don’t allow before Allow; off puts Allow first.
chat.earlier_on_scroll boolean false Older messages load when the thread scrolls to its top; off shows a Load earlier button.
chat.edit_window_seconds integer, 0 to 31536000 172800 Senders may edit a text message this long after sending; 0 turns edits off.
chat.photo_max_bytes integer, 1 to 50000000 20000000 Maximum photo upload size in bytes.
chat.photos boolean true Photo messages enabled.
chat.refuse_blocked_send boolean false A message to someone who blocked the sender is refused (403 forbidden, reason undelivered) and not stored; off accepts it and drops it silently.
chat.short_day_labels boolean false Day separators read day and month only; off adds the weekday, and the year for earlier years.
chat.text_max_length integer, 1 to 10000 4000 Maximum message length.
chat.unsend_window_seconds integer, 0 to 31536000 172800 Senders may delete a message for everyone this long after sending; 0 turns it off. Deleting for oneself is always allowed.
chat.video_max_bytes integer, 1000000 to 209715200 104857600 Maximum video size in bytes; the browser converts to fit.
chat.video_max_seconds integer, 1 to 3600 900 Maximum video length in seconds.
chat.videos boolean true Video messages enabled.
chat.view_once boolean true Senders may mark a photo, video or voice note view once.
chat.voice boolean true Voice notes enabled.
chat.voice_max_bytes integer, 100000 to 52428800 10485760 Maximum voice note size in bytes.
chat.voice_max_seconds integer, 1 to 3600 900 Maximum voice note length in seconds.

Selling services.

Key Type Default Meaning
commerce.catalog_source "webhook", "dashboard" "webhook" Catalog from the catalog callout or the dashboard.
commerce.checkout_url_template https URL or null null Checkout page; placeholders {purchase_id} {item_id} {amount_minor} {currency} {seller_external_id} {buyer_external_id} {lang} {return_url}.
commerce.custom_amount.enabled boolean false Buyers may type an amount, such as a tip.
commerce.custom_amount.max_minor integer, at least 1 100000 Largest amount in minor units.
commerce.custom_amount.min_minor integer, at least 1 100 Smallest amount in minor units.
commerce.enabled boolean false Selling in conversations enabled.
commerce.payment_mode "server_charge", "page_callback", "checkout_url" "server_charge" How purchases are paid.
commerce.payment_window "popup", "same_tab" "popup" Where checkout and top-up pages open.
commerce.show_balance boolean false Show the balance the catalog callout returns.
commerce.topup_url_template https URL or null null Top-up page for the purchase that ran short; same placeholders as checkout.
commerce.trim_whole_prices boolean false A euro price on a purchase card reads 5 € or 5.50 €, never grouped.

Anonymous guests.

Guests get a random id guest:<uuid> and the role in guests.role. The host page keeps their token in localStorage; see the security model.

Key Type Default Meaning
guests.enabled boolean false Allow anonymous guests.
guests.merge_on_login boolean true Merge a recent guest into the member who logs in on that browser.
guests.name_prefix string, up to 32 chars "Guest" Guests show as “<prefix> <6 chars>”.
guests.notify_prompt boolean false While the viewer’s own message is the last one, offer to tell them when the peer replies; tapping sends navigate reason notify for the host to collect an address. Same viewers as the nudge.
guests.notify_prompt_signup boolean false The notify prompt’s button reads Create account and opens guests.nudge.signup_url (navigate reason signup) instead of Notify me; with no signup_url it stays Notify me.
guests.notify_prompt_sticky boolean false Keep the notify prompt once the conversation has a message, until the viewer taps or dismisses it, instead of only while their own message is the last one.
guests.nudge.enabled boolean true Show guests a create-account nudge, and members whose role is guests.role when that is not default_role.
guests.nudge.login_url https URL or null null Where the nudge sends to log in; placeholder {lang}.
guests.nudge.signup_url https URL or null null Where the nudge sends to sign up; placeholder {lang}.
guests.role role key "member" Role given to guests.

Languages and copy.

Key Type Default Meaning
i18n.copy map of "it", "en", "es", "fr" to map of key to string {} Text overrides per language and message key.
i18n.default_lang "it", "en", "es", "fr" "en" Language when nothing else decides.
i18n.languages list of "it", "en", "es", "fr" ["en"] Languages offered.

Limits per role.

One entry per role. A role with no entry gets the defaults shown on each key. null means unlimited.

Counts run over the last 24 hours, except messages per minute. A user who reaches a cap is refused with limit_reached and the reason names the cap. messages_to_unanswered stops a sender from piling up messages before the peer has ever replied, which is the usual guard against unwanted messages to a seller. A perms claim in the client token replaces any of these for that one user.

Key Type Default Meaning
limits map of role key to object {"member":{"messages_per_minute":30,"messages_to_unanswered":null,"new_conversations_per_day":null,"photos_per_day":null,"voice_per_day":100}} Limits per role.
limits.<role>.messages_per_minute integer, at least 1 or null 30 Messages per minute; null is unlimited.
limits.<role>.messages_to_unanswered integer, at least 0 or null null Messages before the peer first replies; null is unlimited.
limits.<role>.new_conversations_per_day integer, at least 0 or null null New conversations per 24h; null is unlimited.
limits.<role>.photos_per_day integer, at least 0 or null null Photos and videos per 24h; null is unlimited.
limits.<role>.voice_per_day integer, at least 0 or null 100 Voice notes per 24h; null is unlimited.

Links to the client’s site.

Key Type Default Meaning
links.open_conversation_url_template https URL or null null Page that opens a conversation; placeholders {peer_external_id} {lang}.
links.profile_sellers_only boolean false The conversation header opens the profile of sellers only.
links.profile_url_template https URL or null null Profile page; placeholders {external_id} {lang}; null lets the host resolve.
links.services_menu boolean true With services_page, buyers also get a Services menu item.
links.services_page boolean false Buyers can open the seller’s services page from a conversation.
links.services_url_template https URL or null null Services page; placeholders {external_id} {lang}; null lets the host resolve.
links.support_email email or null null Shown to banned users.

Moderation.

We host adult content. Sex, nudity, erotic talk and selling sexual content between adults are allowed: the classifiers never flag them and there is no category for them. They look only for the categories below: text and photos after delivery, and calls through Agora’s moderation when moderation.calls.agora is on, with the peer sampling a participant whose Agora task did not start when moderation.calls.fallback_capture is on.

  • Minors: any sign a participant is or could be under age, or any request for content of minors.
  • Trafficking: a third party controls a participant (a “manager” or “owner”, debts paid with sex work, no control of their own money or papers).
  • NonConsent: sextortion and sexual coercion, including threats to show or publish images, and pressing on after a clear no. Agreed role play between adults is not this.
  • Violence, SelfHarm, Hate, Harassment, Doxxing, Fraud: what the names say.
  • IllegalServices, Weapons, Drugs: selling or showing them.
  • ExternalPayment: the parties agree that money for the service changes hands outside your site. A business rule, not a safety one.

Actions: off ignores the category. alert opens a case in the dashboard, sends moderation.flagged, and fires alert rules; the content stays delivered. hold also hides the message or photo from the peer until a moderator acts. block also removes the message or rejects the photo. Every category defaults to alert, and a finding in a category with no key here (some photo categories) acts as alert, so nothing is hidden until you choose to. Most adult sites set Minors, Trafficking and NonConsent to block.

Key Type Default Meaning
moderation.calls.agora boolean true Agora call moderation enabled.
moderation.calls.capture_interval_seconds integer, 5 to 300 10 Seconds between frames a peer captures.
moderation.calls.capture_max_frames integer, 1 to 360 30 Frames captured per participant per call.
moderation.calls.fallback_capture boolean true Peers sample a participant whose Agora task did not start.
moderation.photos boolean true Moderate photos.
moderation.rules.Alcohol "off", "alert", "hold", "block" "alert" Action for Alcohol findings.
moderation.rules.Animals "off", "alert", "hold", "block" "alert" Action for Animals findings.
moderation.rules.Doxxing "off", "alert", "hold", "block" "alert" Action for Doxxing findings.
moderation.rules.Drugs "off", "alert", "hold", "block" "alert" Action for Drugs findings.
moderation.rules.ExternalPayment "off", "alert", "hold", "block" "alert" Action for ExternalPayment findings.
moderation.rules.Fraud "off", "alert", "hold", "block" "alert" Action for Fraud findings.
moderation.rules.Harassment "off", "alert", "hold", "block" "alert" Action for Harassment findings.
moderation.rules.Hate "off", "alert", "hold", "block" "alert" Action for Hate findings.
moderation.rules.IllegalServices "off", "alert", "hold", "block" "alert" Action for IllegalServices findings.
moderation.rules.Minors "off", "alert", "hold", "block" "alert" Action for Minors findings.
moderation.rules.NonConsent "off", "alert", "hold", "block" "alert" Action for NonConsent findings.
moderation.rules.Political "off", "alert", "hold", "block" "alert" Action for Political findings.
moderation.rules.SelfHarm "off", "alert", "hold", "block" "alert" Action for SelfHarm findings.
moderation.rules.Trafficking "off", "alert", "hold", "block" "alert" Action for Trafficking findings.
moderation.rules.Violence "off", "alert", "hold", "block" "alert" Action for Violence findings.
moderation.rules.Weapons "off", "alert", "hold", "block" "alert" Action for Weapons findings.
moderation.text boolean true Moderate text messages.
moderation.videos boolean true Moderate videos.
moderation.voice boolean true Transcribe and moderate voice notes.

Notifications.

In-frame alerts while the chat is open. mondochat never emails your users; see webhooks.

Key Type Default Meaning
notifications.banner boolean true Show a banner on new messages.
notifications.banner_throttle boolean true At most one banner per 5s; off replaces it on every message (the sound stays throttled).
notifications.sound boolean true Play a sound on new messages.
notifications.toast_opens "conversation", "panel" "conversation" Clicking the launcher toast opens its conversation, or only the panel.

Onboarding slides.

Key Type Default Meaning
onboarding.enabled boolean false Show onboarding slides.
onboarding.repeat_hours integer, at least 1 or null null Due again this many hours after it was last shown; null shows it once.
onboarding.reshow_hours integer, at least 0 24 Show again after this many hours.
onboarding.slides map of role key to object {} Slides per role.
onboarding.slides.<role>[].art "composer", "call_button", "incoming_call", "mail" or null null Built-in drawing above the title, in the theme colours.
onboarding.slides.<role>[].body map of "it", "en", "es", "fr" to string {} Body per language.
onboarding.slides.<role>[].bullets list of objects [] Icon bullets.
onboarding.slides.<role>[].bullets[].body map of "it", "en", "es", "fr" to string {} Body per language.
onboarding.slides.<role>[].bullets[].icon "card", "shield", "mail", "lock", "coin" required Bullet icon.
onboarding.slides.<role>[].bullets[].signup map of "it", "en", "es", "fr" to string {} Link text per language that opens guests.nudge.signup_url.
onboarding.slides.<role>[].bullets[].title map of "it", "en", "es", "fr" to string {} Title per language.
onboarding.slides.<role>[].image_url https URL or null null Slide image.
onboarding.slides.<role>[].quote map of "it", "en", "es", "fr" to string {} Highlighted note per language.
onboarding.slides.<role>[].title map of "it", "en", "es", "fr" to string {} Title per language.

One row per ordered role pair; a missing pair allows nothing.

Rows are directional: from is the acting user’s role, to the other user’s. A perms claim in the client token overrides any policy flag (for every to role) and any limit for that one user, for example {"call": false, "photos_per_day": 5}.

Key Type Default Meaning
policy list of objects [{"block":true,"buy":false,"call":false,"from":"member","message":true,"offers":false,"photo_consent_required":false,"photos":true,"require_vouch":false,"see_presence":true,"start_conversation":true,"to":"member"}] One row per ordered role pair; a missing pair allows nothing.
policy[].block boolean true May block the peer.
policy[].buy boolean false May buy from the peer.
policy[].call boolean false May start calls.
policy[].from role key required Acting role.
policy[].message boolean true May send messages.
policy[].offers boolean false May send ad hoc offer cards.
policy[].photo_consent_required boolean false The receiver must accept photos per conversation.
policy[].photos boolean true May send photos.
policy[].require_vouch boolean false Starting needs a vouch token or the session’s peer.
policy[].see_presence boolean true May see the peer’s presence.
policy[].start_conversation boolean true May start a conversation.
policy[].to role key required Target role.

Online status.

Key Type Default Meaning
presence.enabled boolean true Presence enabled.
presence.fanout boolean true Also push presence changes to each peer’s own channel. Turn off once every client subscribes with presence_pass.
presence.in_inbox boolean true Show the online dot and last seen in inbox rows.
presence.show_last_seen boolean true Show “last seen” times.

undefined

Lets people install the chat as an app on their phone and get notifications, without an app store. Turn on enabled only after you fill in the name and a 512 px icon, because it is refused without them.

A person signs in once from your own page, through login_url, and the device then stays signed in for 30 days of use. Pushes show “New message” unless push_preview is on, and only go to people who are offline and have not read the message. Off keeps devices and refuses them until it is turned on again.

Key Type Default Meaning
pwa.enabled boolean false The chat as an installable app: device sign-in, manifest and pushes; off keeps devices but refuses them.
pwa.icon_url https URL or null null Square PNG of at least 512 px, edge to edge with the art inside the centre 80% circle (Android crops it to its shape); required when enabled.
pwa.login_url https URL or null null Page of the client that signs the user in and redirects to a fresh app link; placeholder {lang}.
pwa.name string, up to 45 chars or null null The name under the icon, 1 to 45 characters; required when enabled.
pwa.push_preview boolean false Notifications show the message preview instead of “New message”.

Rate limits.

Key Type Default Meaning
rate_limits.app_requests_per_second integer, 1 to 10000 50 User requests per second per app.

Data retention.

Deletions run daily. null keeps data until the user is deleted through the server API.

Key Type Default Meaning
retention.ip_log_days integer, at least 1 90 Delete IP logs after.
retention.messages_days integer, at least 1 or null null Delete messages after; null keeps.
retention.photos_days integer, at least 1 or null null Delete photos after; null keeps.

User roles.

Key Type Default Meaning
roles list of objects [{"key":"member","label":{"en":"Member"},"seller":false}] User roles.
roles[].key role key required Role key, the value of the role claim.
roles[].label map of "it", "en", "es", "fr" to string {} Display name per language.
roles[].seller boolean false Users with this role sell services.

Blocking and reporting.

Key Type Default Meaning
safety.ban_close_button boolean true The banned panel has its own Close button.
safety.report_reasons boolean true A report asks for a reason; off is a plain confirm.

Webhook event options.

See https://docs.mondochat.io/webhooks/overview/. To notify users while the chat is closed, subscribe an endpoint to message.created, conversation.unread and call.ringing and send your own mail, push or SMS. Unread timers run only while an enabled endpoint subscribes to conversation.unread.

Key Type Default Meaning
webhooks.message_text boolean false message.created carries the text.
webhooks.notify_kinds list of "text", "photo", "video", "voice" ["text","photo","video","voice"] Message kinds that make a first contact or an unread streak.
webhooks.unread_after_minutes list of integer, 1 to 10080 [3] Send conversation.unread at each delay while the recipient still has unread messages; [] never.
webhooks.unread_rearm boolean false After the last delay has fired, the next message opens a new streak, so a recipient who never reads is notified again.

Organising conversations.

Key Type Default Meaning
workspace.aliases boolean false Users may give peers a private name.
workspace.away_reply boolean false Sellers may set a reply sent for them, once a day per chat, while away.
workspace.inbound boolean false Members may take messages from members only.
workspace.notes boolean false Users may keep a private note on a peer.
workspace.pins boolean false Users may pin up to 10 conversations.
workspace.queue boolean false Inbox views, archive, search, spent and purchases, and the sign-up invite.
workspace.quick_replies boolean false Sellers keep up to 20 saved replies and send one with a tap.
workspace.reply_time boolean false Conversations with a seller carry her typical reply time.
workspace.tiers list of objects [] Client tiers, lowest first; users get one by key.
workspace.tiers[].color color #rrggbb required Badge color.
workspace.tiers[].key role key required Tier key, the value of a user’s tier.
workspace.tiers[].label map of "it", "en", "es", "fr" to string {} Display name per language.