Skip to content

Settings

The Settings tab centralizes application-wide options. Changes are staged in the form until you click Save Changes — use Discard to revert the unsaved edits. The full schema is also accessible through the API reference (GET /api/settings, PUT /api/settings).

Controls for the web interface appearance.

  • Language — interface language, with 21 languages available. Default: English.

    Arabic, Bulgarian, Czech, Dutch, English, French, German, Greek, Italian, Japanese, Korean, Lithuanian, Polish, Portuguese (Brazilian), Simplified Chinese, Slovak, Spanish, Traditional Chinese, Turkish, Ukrainian, Vietnamese.

    Every language is kept in sync against the English reference, and counts next to nouns follow each language's own pluralization rules. The 12/24-hour time picker's AM/PM control stays literal "AM"/"PM" in all languages, matching the common Windows convention.

    Coverage is complete across the app, including screens that previously fell back to English: AirPlay creation, status and password controls; licence renewal and support-expiry messages; the usage-data consent prompt and the Privacy section; user management, authentication and API-key errors; settings and firewall errors; prayer-time dropdowns and errors; sign-in failures; radio search and favourites; the accessibility labels on mobile bottom sheets; the jingle Save-targets controls; and the two text-to-speech setup help links, which had been English-only in every locale since they were added.

    Product names (MZAP, AirPlay, iPhone, iPad, Mac) stay untranslated in every language, matching platform convention. Organisation names in the prayer-time calculation methods, and the names of the Islamic legal schools, keep their established form for each language.

  • Time Format — how times are rendered in the UI. Options: 24-hour (14:30) or 12-hour (2:30 PM). Default: 24-hour.

Controls for workspace persistence across sessions. See Workspaces for background on what a workspace contains.

  • Restore Last Workspace on Startup — when enabled, MZAP automatically reopens the workspace that was active when the application last closed. Default: on.
  • Save Workspace on Exit — when enabled, MZAP writes pending workspace changes to disk before shutting down. Default: on.
  • Auto-Save Interval (minutes) — how often MZAP writes workspace changes to disk during normal operation. Default: 5. Range: 060. Set to 0 to disable auto-save (save only on exit or on manual save).

The Launch on Windows Startup toggle starts MZAP automatically the next time you log into Windows. (Windows desktop app only.)

  • Registration is per-user — it needs no administrator rights or UAC prompt and only affects the current Windows user.
  • The toggle takes effect immediately; no restart is needed to register or unregister it.
  • You can also disable it from Task Manager → Startup, where it appears as "MZAP".
  • The entry self-heals: if MZAP is updated and its install location changes, the startup registration is re-pointed at the new location automatically on the next launch.
  • The window opens normally on auto-launch; the Restore Last Workspace on Startup setting above governs whether routing and playback resume.

Controls for application log output. Logs are stored under %APPDATA%\MZAP\logs.

  • Log Level — minimum severity written to the log file. Each level is inclusive: it captures itself plus all higher-severity levels.

    SettingCaptures
    DebugDebug + Info + Warning + Error + Critical
    Info (default)Info + Warning + Error + Critical
    WarningWarning + Error + Critical
    ErrorError + Critical only

    Pick Debug when capturing traces for a support request — it is the most verbose option and records everything the app emits. Switch back to Info or Warning for day-to-day operation to keep log files small. Changes to the log level take effect on the next app restart.

    The setting affects both the log file and console output. Framework noise stays suppressed — ASP.NET Core's own categories remain at Warning and above — so the extra output at Debug is MZAP's own diagnostics.

  • Max Log File Size (MB) — maximum size of a single log file before it is rotated. Default: 10. Range: 1100.

  • Open Log Files Folder — opens the log directory in the system file explorer. Useful when zipping logs to attach to a support ticket.

Global audio playback behavior.

  • Default Crossfade Duration (seconds) — fade-in/fade-out length applied when a track ends and the next one begins in the same player. Default: 5. Range: 010. Set to 0 to disable crossfading (hard cuts). This default can be overridden per playlist.

Zone and player volume can be set in decibels through the API, alongside the existing 0–1 fader value. Both PUT /api/zones/{id}/volume and PUT /api/players/{id}/volume accept an optional volumeDb field:

{ "volumeDb": -20 }

Supply either volume or volumeDb, not both — sending both, or neither, returns 400.

Why it exists: the volume field is a fader position (0.0–1.0), not decibels and not a linear gain. How that position maps to loudness depends on the internal Volume Scale, so the same number can mean different loudness across installations. A dB value is self-describing — it always means the same fader position.

  • Range: 0 dB is unity (full volume); -40 dB is the bottom of the fader and means silence. Values below -40 are clamped to silence rather than rejected.
  • Zone and player responses include a read-only volumeDb alongside volume, so you can read the current level in dB without converting.
  • Clients that only read volume are unaffected — the field is unchanged and the desktop UI still uses it.

The MCP set_player_volume and set_zone_volume tools previously advertised a -100 to 0 dB range, but the fader floor is -40 dB — anything below that collapsed to silence while the tool reported a different figure than requested. The documented range is now -40 to 0, and the tools report -∞ dB (silent) at the floor, matching the REST volumeDb field.

  • Strict zone channels (one zone per channel) — controls whether two zones may target the same device channel. Default: off.
    • Off (default) — overlap is allowed; zones that share a channel sum their audio at that output. The Create/Edit Zone dialog lists every channel and labels occupied ones with the owning zone.
    • On — a channel may belong to only one zone. The dialog disables occupied channels and the API rejects an overlapping zone.

Lets MZAP be controlled from other devices on the same network (other PCs, and — in future — mobile apps). By default MZAP binds to localhost only and is reachable just from the PC it runs on.

  • Allow control from other devices on this network (ExposeToLocalNetwork, off by default) — binds the API and UI to all network interfaces so other devices can reach them.
  • Restart required — the change takes effect only after MZAP is restarted; the UI shows a "restart required" banner until then.
  • Confirmation flow — enabling exposure opens a dialog that warns authentication is off by default and offers to enable it in the same step, shows the LAN URL to use from other devices (e.g. http://192.168.1.20:5000, the API port that serves both the UI and the API), and explains the firewall requirement.
  • Firewall — the installer has a second, unchecked-by-default task, "Allow access from other devices on your network (LAN)", that adds LAN-scoped firewall rules (MZAP API (LAN) / MZAP UI (LAN)). The existing localhost-only rule is unchanged.

When exposure is on, opening http://<lan-ip>:5000 from another device connects to that machine's API for both REST and live (SSE) updates.

When authentication is off and MZAP is exposed to the local network, Settings shows a warning to that effect. The same message and styling is used everywhere the condition is reported — under Network Access and under the MCP server section — because it is a single condition, not two separate problems. Each instance points at the nearest place to fix it.

Shows the state of the built-in MCP server: whether the feature is licensed, the URL to connect to, and how many AI clients are currently connected. It also provides ready-to-copy setup for each supported client:

  • Claude Code — a one-line claude mcp add command.
  • Claude Desktop — a claude_desktop_config.json snippet, pre-filled with the correct URL.
  • Anonymous usage data — whether MZAP may collect anonymous usage data. MZAP asks once, after first-run setup, and the choice can be changed here at any time.

    The app behaves identically whichever answer you give. No usage data is collected yet — the setting records your choice so that nothing is ever collected without it.

The section also links to the privacy policy. See Privacy & Data Collection for everything MZAP sends and when.

Controls for internet radio and other network audio streams.

  • Network Timeout (ms) — how long MZAP waits for a user-initiated stream load to succeed before giving up. Default: 50000. Range: 100060000.
  • Network Buffer (ms) — size of the BASS network buffer. Larger buffers absorb more jitter at the cost of higher memory and longer start-up delay. Default: 30000. Range: 100030000.
  • Pre-Buffer Percent — percentage of the network buffer that must fill before playback starts. Default: 75. Range: 0100. Set to 0 for auto (calculated from buffer length).
  • Stream Stall Timeout (seconds) — how long a stream may stall before MZAP falls over to a local backup track. Default: 5. Range: 130. Disabled when the failover toggle below is off.
  • Fail over to local backup when a stream stalls — enables the stall-to-backup behavior. Default: on. See Stream-outage failover for how to build a player's queue for this.

Both stall controls take effect immediately on save — no restart needed.

  • Playlist Mode — how playlist containers (.m3u, .pls, etc.) referenced by stream URLs are handled. Options:

    • Download First (default) — fetch the playlist, then play the first entry.
    • Disabled — treat the URL as a direct stream.
  • Hide stream URLs for all players — when enabled, player cards and the player detail panel show only the hostname of the stream URL (e.g. radio.example.com) instead of the full URL. Applies to HTTP-based stream URLs only and is the global default for every player. Use this when feeds are licensed or otherwise considered sensitive. Default: off.

  • Show stream URL hide toggle on players — when enabled, an eye icon appears next to Now Playing on each player card so admins can override the visibility of that player's stream URL. The toggle is shown only to admin users and only when the player is loaded from an HTTP URL. Default: off. Per-player state is backed by PUT /api/players/{id}/stream-url-hidden.

    The per-player toggle interacts with the global setting:

    • When Hide stream URLs for all players is off, the toggle hides that single player's URL. Other players keep showing the full URL.
    • When Hide stream URLs for all players is on, the toggle works in reverse — it reveals that one player's URL while every other player stays hidden.

    This lets you globally hide all URLs and selectively unhide one player (e.g. when troubleshooting a feed) without flipping the global setting.

These options keep unattended deployments playing through stalls, dead streams, and extended upstream outages. Except where noted, they are managed through the API (PUT /api/settings).

When a stream stalls longer than the configured threshold, MZAP automatically skips to the next track in the playlist instead of waiting for the stream to recover. Both BASS buffer stalls and position-stuck scenarios (the stream reports Playing but the audio position stops advancing) are detected.

  • StreamStallSkipEnabled — on by default. Toggle off to restore the previous wait-for-recovery behavior.
  • StreamStallSkipSeconds — how long a stall must persist before skipping. Default: 5. Range: 130.

Both now have controls in Network Stream Settings above — you no longer need the API to tune them.

Auto-advance loads (moving to the next track when the current one finishes) use a shorter network timeout than user-initiated loads, so dead streams fail fast and the playlist keeps cycling.

  • StreamAutoAdvanceTimeoutMs — timeout for auto-advance stream loads. Default: 8000 (8s). Range: 200030000. User-initiated loads continue to use the full Network Timeout.

After the exponential-backoff retry attempts are exhausted, MZAP continues retrying at a fixed interval indefinitely instead of giving up. This keeps long-running unattended deployments alive through extended upstream outages.

  • StreamHealthRetryIntervalSeconds — retry interval after backoff is exhausted. Default: 60. Range: 10300. Set to 0 to restore the legacy "give up after backoff" behavior.
  • NetworkUserAgent — User-Agent header sent to stream servers. Defaults to a modern Chrome identifier. Override when a stream host rejects non-browser agents or requires a specific identifier.

Configures the venue location and calculation parameters used by Prayer Time scheduler triggers. The section is collapsed by default; expand it to enter values. While unconfigured, the Prayer Time trigger type in the scheduler still appears but cannot be used.

  • Venue latitude — decimal degrees, north positive, range -90 to 90. Leave empty to disable the prayer feature.

  • Venue longitude — decimal degrees, east positive, range -180 to 180.

  • Use device location — reads coordinates from the browser's geolocation API and rounds to four decimal places (about 11 m precision). Requires HTTPS or localhost and the user's permission. The "Find your coordinates" link opens latlong.net for manual lookup.

  • Clear location — empties both latitude and longitude fields, which disables Prayer Time triggers until a new location is set.

  • Calculation method — chooses the twilight angles used for Fajr and Isha. Pick the one used in your region:

    MethodTypical region
    Muslim World League (default)Worldwide default
    Islamic Society of North AmericaNorth America
    Egyptian General Authority of SurveyEgypt, much of Africa
    University of Islamic Sciences, KarachiPakistan, India, Bangladesh
    Umm al-Qura, MakkahSaudi Arabia
    DubaiUAE
    Institute of Geophysics, TehranIran (Sunni & Shia)
    Shia Ithna Ashari, QumShia communities (Ja'fari fiqh)
  • Asr juristic methodStandard (Shafi'i, Maliki, Hanbali, Ja'fari — shadow length equals object length) or Hanafi (shadow length equals twice the object length, which pushes Asr later in the afternoon).

  • High-latitude rule — adjustment for venues above roughly 48° latitude where the sun never reaches the standard twilight angles in summer or winter. Options:

    • None — use the raw astronomical calculation (may produce no Fajr/Isha at extreme latitudes).
    • Middle of the night — use the midpoint between Maghrib and Sunrise as a fallback.
    • One-seventh of the night — split the night into seven parts.
    • Angle-based — scale the night fraction proportionally to the configured twilight angle.
  • Today's prayer times — preview panel that calls GET /api/prayer/today and displays the five times for the current day in the venue's local time zone, formatted using your Time Format preference. The panel auto-saves the prayer fields before computing, so you can sanity-check edits without first hitting the global Save Changes button. Use it after picking a method to verify the times match what your community expects.

The venue's time zone is taken from the host system's local time zone — there is no separate venue-time-zone setting yet, so run MZAP on a machine set to the venue's local time.

API endpoints exposed by this feature:

  • GET /api/prayer/today — five prayer times for today
  • GET /api/prayer/{date} — five prayer times for a specific date (YYYY-MM-DD)

Both return a 400 when the venue location is not configured.

Configures the providers used by TTS jingles. The section shows a status row for each provider:

  • Windows TTS — always available, no setup needed (offline, uses the host machine's installed voices).
  • Azure Speech (cloud) — disabled until the Cloud TTS license feature is present and an API key + region are configured.
  • ElevenLabs (cloud) — disabled until the Cloud TTS license feature is present and an API key is configured.

Cloud TTS keys are encrypted and scoped to the current Windows user. They are never returned by any API endpoint and never included in workspace exports.

Each cloud provider has a How to get a key link that opens its setup walkthrough in this documentation. It appears in three places:

  • Beside the Set up key / Replace key buttons.
  • Inside the key dialog.
  • As Check the setup steps, directly under a failed Test connection — which is where you actually are when you are stuck.

Windows TTS has no link, because it needs no key. Links open in the default browser on desktop, and in a new tab in the browser client.

Azure Speech gives you ~140 neural voices across 90+ languages. It is optional — the built-in Windows voices work offline with no setup. To use Azure you supply your own API key; Microsoft offers a free tier (F0) covering roughly 0.5 million characters per month.

  1. Create a free Azure account at azure.microsoft.com/free (no charge; the free Speech tier needs no credit-card spend).
  2. In the Azure Portal, choose Create a resource, search for Speech, and select Speech Services → Create.
  3. Set:
    • Resource group — create one or reuse an existing group.
    • Region — pick a region near you (for example westus, eastus, westeurope). Note it down — MZAP asks for it.
    • Name — any name, e.g. mzap-tts.
    • Pricing tierFree F0 for trial use, or Standard S0 for production volume.
  4. After the resource deploys, open it and select Keys and Endpoint.
  5. Copy KEY 1 and note the Location/Region.
  6. In MZAP, go to Settings → Text-to-speech → Azure Speech → Set up key, paste the key and region, click Test connection, then Save.

ElevenLabs provides premium, multilingual neural voices. It is optional — the built-in Windows voices work offline with no setup. To use ElevenLabs you supply your own API key; ElevenLabs offers a free tier (~10,000 credits/month, roughly 10 minutes of generated audio).

  1. Create an account at elevenlabs.io. No credit card is needed for the free tier.

  2. Open your profile menu (top-right) → API Keys, or go directly to elevenlabs.io/app/settings/api-keys.

  3. Click Create API Key and give it a name (e.g. MZAP).

  4. Important — endpoint permissions. If you enable Restrict Key, you must grant the key access to both of these endpoints, or MZAP cannot use it:

    • Text to Speech → Access
    • Voices → Access

    MZAP needs Voices to list the available voices and to validate the key, and Text to Speech to generate the audio. A key restricted to Text to Speech only will fail the connection test with a 401 error. If in doubt, leave Restrict Key off — that grants all endpoints.

  5. Copy the generated key (it starts with sk_). You won't be able to see it again after closing the dialog.

  6. In MZAP, go to Settings → Text-to-speech → ElevenLabs → Set up key, paste the key, click Test connection, then Save.

Once saved, ElevenLabs appears in the Provider dropdown when you create a TTS jingle. Its voices are multilingual — a single voice can speak any supported language, so you can type text in any language regardless of the voice's listed accent.

Both cloud providers require the Cloud TTS license feature — if a provider is greyed out in Settings, your license does not include it.

At the bottom of the Settings tab, Scalar API Docs opens the interactive API reference for the local MZAP instance in your browser. Use it to try endpoints against the running application. The same reference is available here in the docs under API Reference.