Appearance
Settings, card by card
Every field on System › Settings, with the permission that unlocks each card.
The Settings page (/admin/system/settings) is a grid of cards. Each card opens a side panel with one form; the field names below are the form's real input names, which are also the column names on the tenant's kiwire_tenants row (except where the Notes column says otherwise). Hints are the ones the form shows.
A card whose permission you lack still appears but opens on a "not permitted" panel. The page itself needs at least one of the permissions listed here.
Below the cards, Recent changes lists the last edits to this tenant's settings row (who, when, field, old → new), read from the audit trail. Secret fields show a lock instead of the values.
General
Permission: manage-settings-general. Saves to PUT /admin/system/general.
| Field | Meaning | Notes |
|---|---|---|
currency | Default currency | ISO 4217 code, e.g. MYR, USD, EUR. Exactly 3 upper-case letters. |
gst_vat_rate | GST / VAT rate | 0–100, two decimals. "Tax rate applied to billing. Set 0 if not applicable." Used as the default tax rate for payment login methods and the Buy Panel. |
volume_metric | Data transfer reporting metric | Mb or Gb. |
timezone | Time zone | Any PHP timezone identifier. "Default timezone used for reports and scheduling." Every admin date is rendered in this zone and every cron time below is read in it. |
date_format | Date format | One of d-M-Y, d/m/Y, d-m-Y, Y-m-d, m/d/Y, D, d M Y. Display only. |
forgot_password_method | Forgot-password channel | email (default when blank) or sms. Email: the portal's Forgot Password method sends its own email template through its email connector. SMS: the guest enters a phone number, username or email; if an account with a phone number matches, the reset link is texted to that phone through the tenant's first enabled SMS connector. Same expiry, resend cooldown and "if an account matches" answer as email; temporary-access mode is not used over SMS. |
forgot_password_template | Forgot-password template | Id of the message template. The list shows SMS templates and email templates with purpose "forgot password", filtered by the chosen channel. Used for SMS (placeholders {{reset_link}}, {{username}}, {{fullname}}, {{expiry}}, {{expires_in}}); blank sends "Reset your Wi-Fi password: (valid N min)." Email keeps the template set on the login method. |
clear_password_on_reset | Clear password change date on reset | Switch. When on, resetting an account (Accounts › Users or Vouchers reset, or the profile reset schedule) also clears its password change date, so "change on first login" and the password-age rule start again. |
ask_web_push | Ask user for web push | Switch. "Only work if connection is HTTPS and end-user is using Android or Windows (Chrome or Firefox)." |
is_mfactor | 2-factor authentication | Switch, "For Administrator Only" — the tenant-wide flag that administrators are expected to use MFA. In Kiwire 4 MFA is turned on per administrator (Administrators page); this flag is the tenant-level statement of policy and is what KAIA reads when it reports "MFA for admins" in the tenant profile. |
Voucher & Top-up
Permission: manage-settings-prefix. Saves to PUT /admin/system/prefix.
| Field | Meaning | Notes |
|---|---|---|
voucher_prefix | Default voucher prefix | Up to 20 characters, e.g. VCH, KW. Pre-fills the prefix on the voucher generation form and is the prefix the Buy Panel uses for vouchers it sells. |
voucher_engine | Voucher format | sequence (Number in Sequence), unique_id (Unique ID) or random (Random [0-9a-zA-Z]). |
voucher_template | Voucher template | A message template of type voucher — the layout for printed voucher slips. Max 100 chars. |
voucher_limit | Random engine length limit | 1–255. "Warning: short voucher usernames can overlap and limit the number of available names." |
voucher_avoid_ambiguous | Prevent ambiguous characters | Switch. "Exclude visually-similar characters (0/O, 1/I/l) when generating random voucher codes." |
topup_prefix | Default top-up prefix | Up to 20 characters. Pre-fills the prefix on the top-up code generation form. |
allow_topup_voucher | Allow top-up voucher | Switch. "Allow users to top up using voucher codes." |
topup_can_carry_foward | Carry forward top-up | Switch (the column really is spelt foward). "Unused quota carries over to the next billing cycle." |
allow_topup_account | Allow top-up account / user | Switch. "Allow users to top up directly from their account." |
Of these, only the two prefixes and voucher_template are read back by the Kiwire 4 code today: batch voucher generation always produces PREFIX + 8 random upper-case characters regardless of voucher_engine, voucher_limit or voucher_avoid_ambiguous, and the three top-up switches are stored but not consulted by the portal or the admin. They are kept on the row for the legacy portal and for a later pass. See Account, voucher and top-up fields for how codes are actually generated.
Server
Permission: manage-settings-server. Saves to PUT /admin/system/server-config.
| Field | Meaning | Notes |
|---|---|---|
acct_interim_free | Accounting interim interval for free profiles (seconds) | Required, 60–86400. "Minimum 60s. Values below 300s may increase RADIUS server load." Default 3600. Pre-fills the profile form's interim-update field when the profile type is free. |
acct_interim_nonfree | Accounting interim interval for non-free profiles (seconds) | Same range and warning. Default 1800. Pre-fills the field for countdown and expiration profiles. |
Both are only defaults for the profile form: the value actually sent as reply:Acct-Interim-Interval is whatever the profile is saved with, and the profile save floors it at 300 s regardless of what is entered here. | dns_redirect_server | DNS / IP server for redirection | A hostname, IPv4 address or http(s):// URL, max 255. "DNS or IP address used for captive portal redirection." | | captive_trigger_url | URL for captive network trigger | Same format rule. "URL endpoint that triggers the captive portal detection." | | use_ip_as_tenant | Use IP address as tenant | Switch. "Resolve tenant identity using the client IP address." |
The two interim intervals are the only fields on this card the application reads; the other three are stored for the network side and are not consulted by the Laravel code.
Cron timing
Permission: manage-settings-cron. Saves to PUT /admin/system/server.
The panel opens with three notices worth repeating: don't change anything here unless necessary; times are in the tenant's time zone (the General card's timezone); and the format is HH:MM, so 02:00 runs at 2:00 AM local time. Every time field is required.
| Field | Meaning | Notes |
|---|---|---|
cron_auto_update | Auto update check | HH:MM. "Time to check for system updates." |
cron_campaign_last_visit | Campaign check for last visit | HH:MM. "Time to evaluate campaign last-visit triggers." |
cron_run_backup | Run backup database | HH:MM. "Time to run the daily database backup." |
cron_stats_admin | Generate statistics report to administrator | HH:MM. "Time to generate and email admin statistics." |
cron_stats_user | Generate statistics report to user | HH:MM. "Time to generate and email user statistics." |
cron_device_monitor | Device monitoring check | Minutes, 1–255. |
cron_notification_interval | Notification interval | Minutes, 1–255. |
cron_profile_reset_daily | Profile reset — daily | HH:MM. "Time to run the daily profile quota reset." |
cron_profile_reset_weekly | Profile reset — weekly | HH:MM, runs on the weekend. |
cron_profile_reset_monthly | Profile reset — monthly | HH:MM, runs on month end. |
cron_profile_reset_yearly | Profile reset — yearly | HH:MM, runs on 31 Dec. |
cron_account_policy_daily | Account policy — daily | HH:MM. "Time to run daily account policies." |
cron_account_policy_weekly | Account policy — weekly | HH:MM, plus cron_account_policy_weekly_day (0 = Sun … 6 = Sat), "Day of the week the weekly policy runs." |
cron_account_policy_monthly | Account policy — monthly | HH:MM. "Runs on the last day of each month." |
cron_account_policy_yearly | Account policy — yearly | HH:MM. "Runs on 31 Dec each year." |
The four cron_account_policy_* times (and the weekly day) are what the account-policy scheduler reads to decide when each tenant's policies fire. The rest of the times are stored on the tenant row for the scheduler and legacy jobs; profile auto-reset in Kiwire 4 is driven by each profile's own reset_type / reset_schedule (see Zone and profile settings).
Password Policy
Permission: edit-portal-config or edit-portal-templates. Saves to PUT /admin/captive-portal/configuration/password-policy. Moved here from Captive Portal › Configuration on 2026-10-07 because it applies to every user account in the tenant, not to one portal. Fields: pp_enabled (master switch), pp_require_alphabet, pp_require_numeral, pp_require_symbol, pp_not_same_as_username, pp_no_reuse, pp_change_on_first_login, pp_max_failed_attempts and pp_lockout_duration, plus after a change: pp_auto_login (sign the guest in after changing) and pp_change_password_page (published portal template that shows the change-password form). The card summary shows on/off and the active rules.
ISP
Permission: manage-isp-settings. Only shown once Synchroweb has made ISP available to the tenant. The fields added with the subscriber portal (2026-10-07):
| Key | Label | Notes |
|---|---|---|
isp_portal_payment_connector_id | Online payment in the User Portal | A payment-gateway connector, or none. With one, open bills in the subscriber portal get a Pay button; without, subscribers are told to pay by bank transfer quoting their account number. |
isp_plan_change | Plan changes in the User Portal | next (default): the subscriber pays for the new plan now and moves onto it when the current paid period ends (switched by the 30-minute billing run). now: moves on payment; the old plan's unused paid days, at its daily rate, come off the price; any excess stays as account credit; an unpaid change is reverted after a day. off: renew only. Renewing the current plan is always allowed. |
isp_portal_slug | (set from ISP › Overview) | The User Portal subscribers are sent to. Created with Create subscriber portal (a published portal, journey, sign-in page and password sign-in method in the tenant's name, all editable under WiFi Enterprise afterwards) or chosen from existing User Portals. Used for the {{portal_link}} placeholder in ISP payment reminders. |
Consent & Privacy
Permission: manage-consent-settings. Saves to POST /admin/consent/settings. The card only shows when the consent module's settings can be read for this tenant. Values live in the tenant's settings table, not on the tenant row.
| Field | Meaning | Notes |
|---|---|---|
consent_module_enabled | Capture guest consent | Switch, default off. "When on, every captive-portal login shows the consent step before access, and each grant or withdrawal is recorded. When off, no consent page renders and every CRM push is refused (fail-closed)." |
consent_jurisdiction | Primary jurisdiction | One of the jurisdictions the module knows (shown as NONE when unset). "Sets the default policy text on the splash page and the audit labels." |
consent_policy_version | Default policy version | Up to 20 chars. "Display hint only — versioned texts live under Consent Policies." |
consent_marketing_required | Only send marketing messages to guests who agreed to receive them | Switch, default off. When on, campaign notifications go only to guests with marketing consent for the channel (email, SMS or WhatsApp). Expiry and payment reminders are not affected. |
consent_retention_days | Ledger retention (days) | 30–730; default and maximum 730 (2 years). "Records and audit rows older than this may be pruned." |
If the consent tables have not been migrated on the tenant yet, the panel warns that settings can be saved but nothing will be recorded. Policy texts, the per-guest ledger, export and erasure live under Consent Policies and Consent Ledger, linked from the panel.
Organisation
Permission: view-organisation to see the card, edit-organisation to save. Saves to PUT /admin/system/organisation.
| Field | Meaning | Notes |
|---|---|---|
client_id | Client ID | Optional, max 100. |
name | Organisation name | Required, max 120. This is the tenant's display name everywhere. |
industry | Industry | Picked from a fixed list; max 50. |
website | Website | A valid URL, max 255. |
phone | Phone | Max 20. |
address | Address | Max 500. |
logo | Logo | Image upload — PNG, JPG, GIF, WebP or BMP. The form says max 1 MB; the server accepts up to 5 MB. |
Storage usage
Permission: view-organisation. Read-only.
Shows the disk this tenant is using, broken down by category (portals, uploads, database, logs, certificates…), with a Recalculate button (POST /admin/system/storage-usage/recalculate) and the time of the last calculation. Logs and certificates are counted toward the total although the tenant did not create them.
A.I Model
Permission: manage-settings-general. Saves to PUT /admin/system/ai. The card only appears when the AI tables are migrated for the tenant. Values are per-tenant settings (kiwire_tenant_settings, group ai), not tenant-row columns.
| Field | Meaning | Notes |
|---|---|---|
provider | Provider | One of groq, anthropic, openai, gemini, openrouter, minimax. The label next to it says whose key pays ("Kiwire: …" on the shared key, "your key" on BYOK). |
model | Model | Blank = the provider's default. On the shared platform key only models on the platform's list for that provider are accepted; on your own key any model. Max 120 chars. |
temperature | Temperature | 0–2. |
max_tokens | Maximum response tokens | 256–32768. |
byok_key | Your own API key | Optional, max 500 chars. Stored encrypted; the panel only ever shows that a key exists and its last four characters. Only offered when BYOK is allowed for the tenant. |
ssl_verify | Verify SSL | yes / no. |
kaia_enabled | KAIA switch | yes / no, shown when KAIA is licensed for the tenant. |
kaia_interval_hours | KAIA heartbeat interval | 6, 12 or 24 hours. |
kaia_review_days | KAIA daily-review window | 1, 2, 3 or 7 days. |
The panel also has Fetch models (POST /admin/system/ai/models) and Test (POST /admin/system/ai/test) buttons, and shows the tenant's monthly token cap and usage when a cap is set. Which key is used, the model lists and the caps are explained in Keys, models and limits; KAIA itself in KAIA.
MCP Connections
Permission: manage-settings-general. Saves to PUT /admin/system/mcp. Only usable when MCP is allowed for the tenant by the platform; otherwise the panel says so.
| Field | Meaning | Notes |
|---|---|---|
servers[reporting] | Reporting MCP server | yes / no. Read-only captive-portal reports at /mcp/reporting; usernames and device identifiers are masked. |
servers[kaia] | KAIA MCP server | yes / no. Site overview, diagnostics and read-only SQL over the kaia_* views at /mcp/kaia. |
Below the switches the panel lists the tenant's API keys and lets you scope each one to the servers it may call (PUT /admin/system/mcp/keys/{id}), shows how many calls each server has taken, and has a Test button (POST /admin/system/mcp/test) that makes a real call with a chosen key. Client setup is in MCP and external agents.
SMTP
Managed by Synchroweb — the card is not rendered for tenant administrators.
Read-only. Shows the outgoing mail server the tenant is on (host, port, username, masked password, encryption, from address and from name) as synced from the licence server: "This configuration is synced automatically from your license server and is read-only." The only action is Send test (POST /admin/system/smtp/test) to a recipient you type.