{% if panel_favicon_url %} {% endif %}

{% if has_system_alerts %} ⚠️ {% endif %} {{ panel_title or 'Limristem eMail Admin Panel' }}

Hostname: {{ hostname }} — authenticated session for {{ panel_user }}

{% if notice %}
{{ notice }}
{% endif %} {% if error %}
{{ error }}
{% endif %} {% if page == 'dashboard' %}
{% if has_system_alerts %}
⚠️

ATTENZIONE: Rilevati {{ system_issue_count }} avvisi di configurazione o stato del server!

Controlla la box degli avvisi di sistema di seguito per verificare PTR, Record A hostname, MTA-STS, servizi e porte firewall.

Vedi Avvisi
{% endif %}

Avvisi di Sistema e Diagnostica

Diagnostica automatica per PTR, DNS Hostname, MTA-STS, Postfix/Dovecot/Rspamd, Firewall e APT
{% for item in system_alerts %}

{% if not item.ok %} ⚠️ {% else %} {% endif %} {{ item.title }}

{% if item.ok %} ● Attivo / OK {% elif item.level == 'danger' %} ✖ Errore Critico {% else %} ▲ Avviso {% endif %}

{{ item.message }}

{% endfor %}

Overview

{% for key, value in stats.items() %}
{{ key.replace('_', ' ').title() }} {{ value }}
{% endfor %}

Mail traffic (14 days)

Privacy-safe: only counts and sizes by local mailbox — no subjects or bodies. Open statistics · Traffic list

{% if traffic_chart_svg %}
{{ traffic_chart_svg|safe }}
{% else %}

No traffic chart yet. Stats are collected from Postfix logs every few minutes.

{% endif %} {% if mail_summary and mail_summary.today %}
In today{{ mail_summary.today.inbound }}
Out today{{ mail_summary.today.outbound }}
Avg in / day (30d){{ mail_summary.last_30_days.avg_inbound_per_day }}
Avg out / day (30d){{ mail_summary.last_30_days.avg_outbound_per_day }}
{% endif %}

System Status

{% if system %}
Uptime {{ system.uptime }}
CPU {{ system.cpu.percent }}% Load: {{ system.cpu.load_1|round(2) }}, {{ system.cpu.load_5|round(2) }}
Memory {{ system.ram.percent }}% {{ system.ram.used_str }} / {{ system.ram.total_str }}
Disk {{ system.disk.percent }}% {{ system.disk.used_str }} / {{ system.disk.total_str }}
{% endif %}

Recent queue items

{% if recent_queue %} {% for item in recent_queue %} {% endfor %}
Queue IDSenderRecipients
{{ item.queue_id }} {{ item.sender }} {% for rcpt in item.recipients or [] %}
{{ rcpt.address }}
{% endfor %}
{% else %}

Queue is currently empty.

{% endif %}

Recent backups

{% if recent_backups %} {% for item in recent_backups %} {% endfor %}
NamePath
{{ item.name }} {{ item.path }}
{% else %}

No local backup runs found yet.

{% endif %}
{% elif page == 'traffic' %}

Mail traffic

Only local mailbox, direction, size and time — no subjects, bodies or remote addresses.

Statistics
{% for item in traffic_items %} {% else %} {% endfor %}
WhenDirectionMailboxSize
{{ item.event_at }} {{ 'Received' if item.direction == 'inbound' else 'Sent' }} {{ item.mailbox }} {{ item.size_human }} ({{ item.size_bytes }} B)
No traffic events yet. Wait for the collector timer or open Statistics and click “Collect now”.
{% elif page == 'stats' %}

Statistics

{{ mail_summary.privacy_note if mail_summary else 'Privacy-safe traffic statistics.' }} Retention: {{ mail_summary.retention_days if mail_summary else '—' }} days.

{% if mail_summary %}
Today in / out{{ mail_summary.today.inbound }} / {{ mail_summary.today.outbound }}
7d avg / day in{{ mail_summary.last_7_days.avg_inbound_per_day }}
7d avg / day out{{ mail_summary.last_7_days.avg_outbound_per_day }}
30d avg / day in{{ mail_summary.last_30_days.avg_inbound_per_day }}
30d avg / day out{{ mail_summary.last_30_days.avg_outbound_per_day }}
365d avg / month in{{ mail_summary.last_365_days.avg_inbound_per_month }}
365d avg / month out{{ mail_summary.last_365_days.avg_outbound_per_month }}
{% endif %}

Daily chart ({{ stats_days }} days)

{% if traffic_chart_svg %}{{ traffic_chart_svg|safe }}{% else %}

No data

{% endif %}

By day

{% for row in stats_daily|reverse %} {% else %} {% endfor %}
DayInOutIn bytesOut bytes
{{ row.day }} {{ row.inbound_count }} {{ row.outbound_count }} {{ row.inbound_bytes }} {{ row.outbound_bytes }}
No daily data yet.

By mailbox ({{ stats_days }} days)

{% for row in stats_mailboxes %} {% else %} {% endfor %}
MailboxInOutIn bytesOut bytes
{{ row.mailbox }} {{ row.inbound_count }} {{ row.outbound_count }} {{ row.inbound_bytes }} {{ row.outbound_bytes }}
No per-mailbox data yet.
{% elif page == 'domains' %}

Domains

Add domain
{% if domains %} {% for domain in domains %} {% endfor %}
DomainAccountsAliasesRedirectsStatusOpen
{{ domain.name }} {{ domain.account_count }} {{ domain.alias_count }} {{ domain.redirect_count }} {{ 'active' if domain.is_active else 'inactive' }} Manage
{% else %}

Create your first domain to manage accounts, aliases, redirects and DKIM.

{% endif %}
{% if show_create_form %}

Create domain

Close
{% endif %} {% elif page == 'domain-detail' %}

Back to domains

{{ selected_domain.name }}

Add domain
Max accounts{{ selected_domain.max_accounts_display }}
Used accounts{{ selected_domain.used_accounts }}
Available accounts{{ selected_domain.available_accounts }}
Aliases{{ selected_domain.alias_count }}
Redirects{{ selected_domain.redirect_count }}
Status{{ 'Active' if selected_domain.is_active else 'Inactive' }}
DNS provider{{ selected_domain.dns_provider or 'manual' }}
{% if active_domain_tab == 'settings' %}

Domain settings

DKIM rotation

Active selector: {{ selected_domain.dkim_selector or 'none' }} {% if selected_domain.dkim_rotated_at %} · last rotation {{ selected_domain.dkim_rotated_at }}{% endif %}

{% if selected_domain.dkim_previous_selector %}

Previous selector kept for overlap: {{ selected_domain.dkim_previous_selector }} {% if selected_domain.dkim_previous_expires_at %} until {{ selected_domain.dkim_previous_expires_at }}{% endif %}

{% endif %}

Private key path: {{ selected_domain.dkim_private_path or 'not generated yet' }}

{{ selected_domain.dkim_public_key or 'Generate DKIM to populate the public record.' }}

DNS provider (Cloudflare)

{% if selected_domain.dns_has_api_token %} {% endif %}

Last sync: {{ selected_domain.dns_last_sync_status or 'never' }}

{% elif active_domain_tab == 'accounts' %}

Accounts

Add account
{% if show_create_form %}

Send limits: leave 0 to inherit global service limits.

{% endif %} {% for account in domain_accounts %} {% endfor %}
Email Storage quota Send limits (0=global) Effective send Password Status Suspend / restore Delete
{{ account.email }}

burst / min / hour / day / week / month

{{ account.effective_send_rate_per_hour or 0 }}/h · {{ account.effective_send_rate_per_day or 0 }}/d · {{ account.effective_send_rate_per_month or 0 }}/mo
{{ 'Active' if account.is_active else 'Suspended' }}
{% elif active_domain_tab == 'aliases' %}

Aliases

Add alias
{% if show_create_form %}
{% endif %} {% for alias in domain_aliases %} {% endfor %}
AliasDestinationActiveActions
{{ alias.source }} {{ alias.destination }} {{ 'yes' if alias.is_active else 'no' }}
{% elif active_domain_tab == 'redirects' %}

Redirects

Add redirect
{% if show_create_form %}
{% endif %} {% for redirect in domain_redirects %} {% endfor %}
RedirectTargetKeep copyActiveActions
{{ redirect.source }} {{ redirect.target_email }} {{ 'yes' if redirect.keep_copy else 'no' }} {{ 'yes' if redirect.is_active else 'no' }}
{% elif active_domain_tab == 'autoresponders' %}

Autoresponders

Vacation replies are delivered via Dovecot Sieve when enabled on a mailbox.

{% for account in domain_accounts %}

{{ account.email }}

{% set ar = account.autoresponder if account.autoresponder else none %}
{% else %}

Create mailboxes first to configure autoresponders.

{% endfor %}
{% else %}

Suggested DNS records

{% for key, value in dns_records.items() %}

{{ key }}

{{ value }}
{% endfor %}
{% endif %}
{% elif page == 'queue' %}

Mail Queue

{% if queue %} {% for item in queue %} {% endfor %}
Queue IDQueueSenderRecipientsReasonActions
{{ item.queue_id }} {{ item.display_state or '—' }} {{ item.sender }} {% for rcpt in item.recipients or [] %}
{{ rcpt.address }}
{% endfor %}
{{ item.display_reason or '—' }} {% for action in ['hold', 'release', 'requeue', 'delete'] %}
{% endfor %}
{% else %}

Queue is empty.

{% endif %}
{% elif page == 'import' %}

Mailbox import

Transfer every folder and message (including Sent) from a remote IMAP server into a local Limristem mailbox. Jobs run in a dedicated queue.

{% if active_import_tab == 'new' %}

Source IMAP credentials

Choose the local destination account, then enter the remote mailbox credentials. Use Test connection before queuing a full import.

{% if not import_accounts %}

Create at least one local account before importing mail.

{% else %}

Passwords are encrypted at rest. Plain IMAP is only for trusted networks; prefer IMAP SSL or STARTTLS.

{% endif %}
{% elif active_import_tab == 'bulk' %}

Bulk import from file

Download the example file, fill it with every mailbox you want to migrate (one entry per account, with the remote IMAP credentials), then upload it. A separate import job is queued for each account and jobs run one by one with live progress on the Jobs tab.

Up to 500 accounts per file (2 MiB max). If destination_email is omitted, source_username is used. Missing mailboxes on existing domains are created automatically with the source password.

{% if bulk_import_result %}

Bulk import result

{{ bulk_import_result.queued_count }} job(s) queued out of {{ bulk_import_result.total }} entries {% if bulk_import_result.accounts_created %} · {{ bulk_import_result.accounts_created }} account(s) created{% endif %} {% if bulk_import_result.error_count %} · {{ bulk_import_result.error_count }} row(s) skipped{% endif %}

{% if bulk_import_result.queued %} {% for item in bulk_import_result.queued %} {% endfor %}
RowDestinationJobAccount
{{ item.row }} {{ item.destination_username }} #{{ item.id }} {% if item.account_created %}created{% else %}existing{% endif %}
{% endif %} {% if bulk_import_result.errors %} {% for item in bulk_import_result.errors %} {% endfor %}
RowDestinationProblem
{{ item.row }} {{ item.destination_email or '—' }} {{ item.detail }}
{% endif %}
{% endif %} {% else %}

Import jobs

Live progress refreshes every 2 seconds while jobs are pending or running.

{% if import_jobs %} {% for job in import_jobs %} {% endfor %}
ID Status Destination Source Progress Transferred Speed ETA Folder Actions
{{ job.id }} {{ job.status }} {{ job.destination_username }} {{ job.source_username }}
{{ job.source_host }}:{{ job.source_port }} ({{ job.source_protocol }})
{{ '%.1f'|format(job.progress_percent) }}% · {{ job.messages_done }}/{{ job.messages_total }} msgs · folders {{ job.folders_done }}/{{ job.folders_total }}
{{ job.bytes_done_human }}
of {{ job.bytes_total_human }} · {{ job.bytes_remaining_human }} left
{{ job.speed_human }} {{ job.eta_human or '—' }} {{ job.current_folder or '—' }} {% if job.status_message %}
{{ job.status_message }}
{% endif %} {% if job.last_error %}
{{ job.last_error }}
{% endif %}
{% if job.status in ['pending', 'running'] %}
{% endif %} {% if job.status not in ['running'] %}
{% endif %}
{% else %}

No import jobs yet. Start one from the New import tab.

{% endif %}
{% endif %}
{% elif page == 'backups' %}

Backups

{% if active_backup_tab == 'schedules' %} {% if action == 'create' or selected_backup_schedule.get('id') %}

{{ 'Edit schedule' if selected_backup_schedule.get('id') else 'Create schedule' }}

Cron-style schedule fields: minute hour day month weekday. Use * to match any value.

Cancel

Limristem eMail uses the database credentials already stored in the main configuration file. A schedule only decides whether the MariaDB dump is included.

{% else %}

Backup schedules

Create new schedule
{% if backup_schedules %} {% for item in backup_schedules %} {% endfor %}
NameScheduleStorageDBRedisCompressionStatusActions
{{ item.name }} {{ item.cron_expression }} {{ item.storage_id or 'Local only' }} {{ item.include_database }} {{ item.include_redis }} {{ item.compression }} {{ item.enabled }} Edit
{% else %} {% endif %}
{% endif %} {% elif active_backup_tab == 'storages' %} {% if action == 'create' or selected_backup_storage.get('id') %}

{{ 'Edit storage' if selected_backup_storage.get('id') else 'Create storage' }}

Cancel

When encryption is enabled, Limristem eMail keeps only the public key for future backup exports and prompts you to download the private key once.

{% else %}

Backup storages

Create new storage
{% if private_key_download_token %}
New encryption key ready.
{% endif %} {% if backup_storages %} {% for item in backup_storages %} {% endfor %}
NameTypeTargetEncryptionActions
{{ item.name }} {{ item.type }} {{ item.bucket or item.host or item.path or 'local' }} {{ item.encrypt }} Edit
{% else %} {% endif %}
{% endif %} {% elif active_backup_tab == 'runs' %}

Available local backup runs

{% if backup_runs %} {% for item in backup_runs %} {% endfor %}
NamePathMetadata
{{ item.name }} {{ item.path }} {{ item.metadata or 'n/a' }}
{% else %}

No local backups found.

{% endif %}
{% else %}

Global backup settings

{% for key in backup_field_order %} {% endfor %}
SettingValue
{{ backup_field_labels.get(key, key) }} {% if key in backup_numeric_fields %} {% elif backup_field_options.get(key) %} {% else %} {% endif %}
{% endif %}
{% elif page == 'security' %}

Security & Authentication

MFA protection, IP access control (Banned IPs) and Firewall rules.

{% if active_security_tab == 'dashboard' %}

TOTP (Authenticator)

{% if mfa_status and mfa_status.totp_enabled %} ● Attivo {% elif mfa_status and mfa_status.totp_pending %} ▲ In attesa {% else %} ✖ Non attivo {% endif %}

Autenticazione TOTP con app authenticator per proteggere l'accesso al pannello admin ed API.

Configura TOTP →

SMS OTP

{% if mfa_status and mfa_status.sms_enabled %} ● Attivo {% else %} ✖ Non attivo {% endif %}

{% if mfa_status and mfa_status.sms_enabled %} Codici OTP via SMS attivi per {{ mfa_status.sms_phone_masked }}. {% else %} Autenticazione mediante codice di sicurezza SMS monouso non attiva. {% endif %}

Configura SMS OTP →

SMS Providers

{% if sms_provider_configured %} ● Configurato{% if sms_provider_names %} ({{ sms_provider_names }}){% endif %} {% else %} ✖ Non configurato {% endif %}

Integrazione con i gateway SMS (Crisaleo SMS e SMS2SMS) per l'invio dei messaggi.

Gestisci Providers →

Protezione Accessi

{% if firewall_config and firewall_config.get('firewall-enabled', 'yes') == 'yes' %} ● Firewall Attivo {% else %} ✖ Firewall Disattivato {% endif %}

IP attualmente bannati: {{ bans|length }} | Regole firewall attive: {{ firewall_rules|length }}

Gestisci Accessi →
{% elif active_security_tab == 'access' %}

Banned IPs

{% for item in bans %} {% else %} {% endfor %}
CreatedIPReasonSourceServicesAction
{{ item.created_at or '—' }} {{ item.ip }} {{ item.reason }} {{ item.source or 'manual' }} {{ item.services or item.jail or '—' }}
No banned IPs found.

Firewall

{% for rule in firewall_rules %} {% endfor %}
Port / group / rangeProtocolSource IP / subnetStatusActions

Use one row per nftables rule. Ports may be a single port, a group of ports, or ranges. Leave source empty to allow any origin.

{% elif active_security_tab == 'config' %}

TOTP and/or SMS OTP protect the web panel and the management API. SMTP/IMAP/POP cannot do interactive OTP mid-session — for mailboxes use app passwords (API /accounts/{id}/app-passwords) and optionally require_app_password.

TOTP (authenticator app)

Status: {% if mfa_status and mfa_status.totp_enabled %}enabled {% elif mfa_status and mfa_status.totp_pending %}pending confirmation {% else %}disabled{% endif %}

{% if totp_enroll %}

1. Scansiona il QR Code o copia la chiave Secret nella tua app Authenticator (Google Authenticator, Authy, 1Password):

{{ totp_enroll.secret }}
{% if totp_enroll.qr_data_url %} TOTP QR Code {% elif totp_enroll.qr_svg %}
{{ totp_enroll.qr_svg | safe }}
{% endif %}

URI TOTP: {{ totp_enroll.provisioning_uri }}

{% else %}
{% if mfa_status and (mfa_status.totp_enabled or mfa_status.totp_pending) %}
{% endif %} {% endif %}

SMS OTP

Status: {% if mfa_status and mfa_status.sms_enabled %}enabled ({{ mfa_status.sms_phone_masked }}) {% else %}disabled{% endif %}

SMS Providers Configuration

Seleziona la scheda del provider SMS da configurare (Crisaleo SMS o SMS2SMS).

{% if active_provider_tab == 'crisaleo' %} {% for provider in mfa_providers or [] %} {% if provider.code == 'crisaleo' %}

Crisaleo SMS

Configurazione del gateway Crisaleo SMS per invio OTP. Headers: X-Client-Id, X-Client-Secret, X-Api-Key.

{% if provider.enabled %} ● Abilitato {% else %} ✖ Disabilitato {% endif %}
{% endif %} {% endfor %} {% elif active_provider_tab == 'sms2sms' %} {% for provider in mfa_providers or [] %} {% if provider.code == 'sms2sms' %}

SMS2SMS

Configurazione ed instradamento del gateway SMS2SMS. Headers: X-Client-Id, X-Client-Secret, X-Api-Key.

{% if provider.enabled %} ● Abilitato {% else %} ✖ Disabilitato {% endif %}
{% endif %} {% endfor %} {% endif %}
{% endif %}
{% elif page == 'operations' %}

Operations

Deliverability, outbound IP reputation self-checks, connectivity probes, inbound DNSBL helpers.

Deliverability check

End-to-end connectivity

TCP + TLS probes to SMTP/IMAP/HTTPS (no mailbox password required).

Inbound DNSBL (Rspamd)

{{ rbl_config.warning }}

Aggiornamento Pacchetti di Sistema (APT)

{% if apt_job and apt_job.running %} ⚙️ In Queue / In Esecuzione {% elif apt_job and apt_job.status == 'success' %} ● Completato con Successo {% elif apt_job and apt_job.status == 'failed' %} ✖ Errore Aggiornamento {% endif %}
{% if apt_job and apt_job.running %}

⚙️ Aggiornamento APT in corso in background...

L'operazione apt-get update && apt-get full-upgrade -y è in coda ed in esecuzione. Il pulsante è temporaneamente disattivato per evitare avvii multipli.

Avviato alle: {{ apt_job.started_at }}

{% else %}

Esegue apt-get update e apt-get full-upgrade -y in modalità 100% autonoma ed asincrona (in queue) senza bloccare la navigazione.

{% if apt_job and apt_job.completed_at %}

Ultima esecuzione: {{ apt_job.completed_at }} (Esito: {{ apt_job.status }})

{% endif %}
{% endif %}
{% if operations_result %}

Last result

{{ operations_result }}
{% endif %} {% if reputation_history %}

Recent IP reputation checks

{% for row in reputation_history %} {% endfor %}
WhenIPSourceListedDetail
{{ row.checked_at }} {{ row.entity_value }} {{ row.source }} {{ 'yes' if row.listed else 'no' }} {{ row.detail or '' }}
{% endif %}
{% elif page == 'topology' %}

Topology wizard

How this instance is deployed: Standalone, Routed Mesh, or Storage Cluster.

Mode{{ topology.label }} ({{ topology.mode }})
Local server ID{{ topology.local_server_id }}
Internode auth{{ 'configured' if topology.internode_configured else 'not set' }}

Choose deployment mode

{% for mode in topology_modes %} {% endfor %}
Routed Mesh options
Storage Cluster options
{% if internode_token_once %}
Internode token (copy now):
{{ internode_token_once }}
{% endif %}

Registered servers

{% for s in topology_servers %} {% else %} {% endfor %}
IDNameHostnameSMTPRoleLocalActive
{{ s.server_id }} {{ s.display_name }} {{ s.hostname }} {{ s.smtp_host }}:{{ s.smtp_port }} {{ s.role }} {{ 'yes' if s.is_local else 'no' }} {{ 'yes' if s.is_active else 'no' }}
No peers registered (standalone or not yet joined).
{% elif page == 'logs' %}

Logs

{% for log_name in allowed_logs %} {{ log_name }} {% endfor %}
{{ log_content }}
{% elif page == 'settings' %}

Settings

{% if active_settings_tab == 'general' %}

General settings

Stable is the production package feed. Nightly points at the experimental build channel; only use it on non-production nodes.

Max size: 512 KB
{% if settings_info.get('panel_favicon_path') %}
{% endif %}

Version and updates

Hostname{{ settings_info.get('hostname', hostname) }}
Update channel{{ settings_info.get('update_channel', 'stable') }}
Check endpoint{{ settings_info.get('update_check_url') or (settings_info.get('update_status') or {}).get('endpoint', '—') }}
Current version{{ settings_info.get('current_version', 'unknown') }}
Latest version{{ (settings_info.get('update_status') or {}).get('latest_version', 'not checked yet') }}
Update available{{ 'yes' if (settings_info.get('update_status') or {}).get('update_available') else 'no' }}
{% elif active_settings_tab == 'webmail' %}

Webmail (Roundcube)

Gestisci l'installazione disaccoppiata della Webmail Roundcube, aggiornamenti autonomi ed impostazioni SSL/Proxy.

Stato Webmail {% if webmail.get('installed') %} ● Installata e Attiva {% else %} ✖ Non Installata {% endif %}
Versione Roundcube {{ webmail.get('version') or 'N/A' }}
Aggiornamento Automatico
URL Accesso Webmail {% if webmail.get('installed') %} 🌐 Apri /mail 🌐 Apri /webmail {% else %} Installazione richiesta per accedere a /mail e /webmail {% endif %}
{% if not webmail.get('installed') %}
{% else %}
{% endif %}
{% elif active_settings_tab == 'ssl' %}

Shared TLS certificate

{% if ssl_info.get('cert_info') %} {% endif %}
Status{{ ssl_info.get('status', 'unknown') }}
Mode{{ ssl_info.get('mode', 'unknown') }}
Hostname{{ ssl_info.get('hostname', hostname) }}
Certificate path{{ ssl_info.get('cert_path', 'N/A') }}
Key path{{ ssl_info.get('key_path', 'N/A') }}
Subject{{ ssl_info['cert_info'].get('subject', 'N/A') }}
Issuer{{ ssl_info['cert_info'].get('issuer', 'N/A') }}
Valid From{{ ssl_info['cert_info'].get('not_valid_before', 'N/A') }}
Valid To{{ ssl_info['cert_info'].get('not_valid_after', 'N/A') }}
{% if ssl_info.get('certs_match') %}

The same certificate is reused for Postfix, Dovecot, and the HTTPS endpoints served by Nginx.

{% else %}

Notice: Postfix and/or Dovecot are using different certificates!

{% if ssl_info.get('postfix_cert_info') %} {% endif %} {% if ssl_info.get('dovecot_cert_info') %} {% endif %}
Postfix Cert Path{{ ssl_info.get('postfix_cert_path', 'N/A') }}
Postfix Cert Subject{{ ssl_info['postfix_cert_info'].get('subject', 'N/A') }}
Dovecot Cert Path{{ ssl_info.get('dovecot_cert_path', 'N/A') }}
Dovecot Cert Subject{{ ssl_info['dovecot_cert_info'].get('subject', 'N/A') }}
{% endif %}

SSL actions

{% elif active_settings_tab == 'limits' %}

Service limits

Message size, recipients, send rates, Rspamd scores, and fail2ban jail thresholds (maxretry / findtime / bantime per jail).

{% for key, value in limits.items()|sort %} {% endfor %}
KeyValue
{{ limit_field_labels.get(key, key) }}
{{ key }}
{% else %}

API Credentials

Admin user{{ api_info.get('api_admin_user', 'N/A') }}
Endpoint{{ api_info.get('api_endpoint', 'N/A') }}
Hostname{{ api_info.get('hostname', 'N/A') }}

API Usage

Authenticate using HTTP Basic Auth with your API admin credentials.

Example requests

curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}health
curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}domains
curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}accounts
{% endif %}
{% elif page == 'limits' %}

Service limits & anti-spam

Auth lockouts, max message size, SMTP rates, per-user send quotas (Rspamd), and fail2ban jail thresholds (maxretry / findtime / bantime).

{% for key, value in limits.items()|sort %} {% endfor %}
ParameterValue
{{ limit_field_labels.get(key, key) }}
{{ key }}
{% elif page == 'api' %}

API Credentials

Admin user{{ api_info.get('api_admin_user', 'N/A') }}
API endpoint{{ api_info.get('api_endpoint', 'N/A') }}
Hostname{{ api_info.get('hostname', 'N/A') }}
{% if generated_api_password %}
New API password: {{ generated_api_password }}
Save this password now — it will not be shown again. Only the hash is stored.
{% endif %}

API Usage

Authenticate using HTTP Basic Auth with your API admin credentials.

Example requests

curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}health
curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}domains
curl -u <user>:<pass> {{ api_info.get('api_endpoint', '') }}accounts

Available endpoints

MethodPathDescription
GET/healthHealth check (public)
GET/health/detailsDetailed health (admin)
GET/POST/domainsList / create domains
GET/POST/accountsList / create accounts
GET/POST/aliasesList / create aliases
GET/POST/redirectsList / create redirects
GET/POST/reputationList / create reputation records
GET/admin/queueMail queue management
GET/admin/bansIP ban management
GET/PATCH/admin/limitsService limits
GET/PATCH/admin/backupsBackup configuration
GET/admin/sslShared TLS certificate status
POST/admin/ssl/selfsignedGenerate a self-signed certificate
POST/admin/ssl/letsencryptRequest a Let's Encrypt certificate
POST/admin/ssl/manualUpload a manual PEM certificate and key
{% endif %}

Accessibility

Text size
Strumenti di Accessibilità