Cloud Sync (no public IP or VPN), the provisioning script, hotspot pages and troubleshooting.

MikroTik with SimpliFi

How ISPs connect MikroTik RouterOS routers to SimpliFi (module M1), and how it works under the hood. Works with RouterOS 6.49+ and 7.x on any MikroTik with internet access.


1. Pick a connection mode

Mode Use it when What the router needs How customers get access
Cloud Sync (default) Almost always. Works behind NAT, CGNAT, LTE, Starlink — no public IP, no VPN, no port forwarding. Outbound internet (HTTPS to your SimpliFi address). SimpliFi queues changes; the router checks in every 20 s. Paying customers get online instantly from a pre-loaded pool of logins.
Direct API The router has a public IP (or a port forward) and you want changes applied in real time. RouterOS 7 REST (www-ssl, port 443) or the classic API (api 8728 / api-ssl 8729) reachable from your SimpliFi server. SimpliFi creates hotspot users directly over the API.
RADIUS Large networks that already run FreeRADIUS (see docs/RADIUS.md). A FreeRADIUS server reading the SimpliFi database; outbound internet for Cloud Sync. Logins are checked by RADIUS. The router still checks in through Cloud Sync for health, blocks, IP bindings and disconnects.

Unlike SopraEnt, SimpliFi does not charge per router or per WAN.


2. Add a MikroTik router — the 3-step wizard

Devices → MikroTik Routers (/admin/mikrotik) is the home of your routers: All / Online / Offline tabs, search, 5 / 10 / 25 / 50 / All per page, and for each router its provisioning state, CPU, memory, status, connection (Cloud Sync / Direct API / RADIUS), health and the remote-access switch. The three buttons: Watch Tutorial (the platform's tutorial video when set, otherwise this guide), Add New Site (a modal: site name + automatic slug — the new site's portal link is shown afterwards) and Link a MikroTik (orange), which opens the wizard. Choosing MikroTik in the generic Router setup assistant opens the same wizard — there is one MikroTik flow, and the wizard hands over to the assistant's verification checklist at the end.

Step 01 — Connection

  • MikroTik Identity — pre-filled MikroTik-1, MikroTik-2 … (the next free name); change it if you like. It becomes the router's identity.
  • Site — pick one, or + Add new site right there.
  • Router has Wireless — switch it on when the MikroTik has WiFi: enter the WiFi SSID customers will see (your business name is pre-filled) and, optionally, a WPA2 password. Leave the password empty for an open network — the usual hotspot setup, customers log in on your SimpliFi page instead.
  • Advanced (collapsed): the connection method. Cloud Sync is the default; Direct API asks for the router address, API type, user and password; RADIUS for the RADIUS server IP and shared secret.

Press Next. You can leave at any time: the wizard keeps its state on the router and Resume setup (dashboard, Routers & Controllers, MikroTik Routers) brings you back to the right step.

Step 02 — Device Details

One command card — the whole card is a button, Click to copy:

/tool fetch mode=https url="https://<your SimpliFi>/api/devices/<token>/provision.rsc" dst-path=simplifi.rsc; :delay 2s; /import simplifi.rsc; /file remove [find where name="simplifi.rsc"];
  1. On a computer connected to the MikroTik open WinBox (or WebFig in a browser), log in and click New Terminal.
  2. Paste the command (right-click › Paste) and press Enter.
  3. Watch the terminal-style status on the page: “$ Paste the provisioning command in your MikroTik terminal to begin” with Attempt N of 300 (it polls every 2 seconds for about 10 minutes). When the router checks in the step ticks green and the wizard moves to step 03 by itself.

mode=https appears only when SimpliFi is served over https — on a plain-http development server the command uses mode=http and the page shows a yellow note: production must be https.

What the link script does (stage 1 — minimal and safe): sets the identity you chose, the time zone and NTP, installs the simplifi-sync scheduler (every 20 seconds) and runs the first check-in, which reports the RouterOS version, board, every interface (name, type, link, MAC, wireless capability), existing bridges and hotspot servers, the internet (WAN) interface with its address, the public IP and the cloud DNS name. Nothing about the hotspot is touched yet. Running it again is safe.

RouterOS 7.17+ device-mode. If the device reports “not allowed by device-mode”, open the MikroTik terminal and run /system/device-mode update mode=advanced, unplug the power cord for 10 seconds, then restore power before retrying the provisioning command. (Device-mode can block fetch, the scheduler and scripts; a reboot is not enough.)

Prefer WinBox menus? Download the link script (.rsc) from the page, drag it into WinBox Files, then System › Scripts › +, paste the file's contents into Source, tick every policy, OK → Run Script (or /import file-name=simplifi.rsc in a terminal).

Having trouble? (also on the page)

Symptom Fix
Nothing happens, “could not resolve”, wrong date /ping 8.8.8.8 count=3 and /ping google.com count=3. DNS: /ip dns set servers=8.8.8.8,1.1.1.1 allow-remote-requests=yes. Clock: /system clock print, or turn on System › NTP Client (time.google.com). HTTPS needs a correct clock.
No internet on the router Check the cable on ether1 and IP › DHCP Client (or your PPPoE / LTE client).
“failure: … SSL” / certificate errors on an old RouterOS Upgrade RouterOS (System › Packages › Check for updates). One-time fallback: paste the same command with mode=http, then upgrade before going live.
“not allowed by device-mode” See the note above: mode=advanced, power off for 10 s, power on, paste again.
“404 Not found” when fetching Wrong or regenerated token — copy the command again from this page.
The command ran but SimpliFi still waits /log print where message~"SimpliFi" shows what happened; /system scheduler print must list simplifi-sync enabled. If you filter the output chain, allow HTTPS (TCP 443) to your SimpliFi host.

Someone else setting it up? The page also sends the command to your technician by SMS, WhatsApp or a private link (expires after 48 hours).

Direct API routers show Test connection instead of the command. Create the simplifi user and switch on the API first (§3); a successful test reads the router's interfaces over the API and moves to step 03.

Step 03 — Service Setup (Configure Hotspot)

Shown only after the router has checked in; every list comes from the router itself.

  • Ethernet Ports — tick the ports your access points plug into. The internet port is shown as ether1 — Internet (WAN) and cannot be ticked; ports that are already in a bridge or run a hotspot carry a hint. The ticked ports move into bridge-hotspot.
  • Wireless (when the router has radios) — SSID, security (open or WPA2), band, and Create the WiFi network for me. RouterOS 7.13+ (wifi) and 7.x wifiwave2 use the new WiFi menus, RouterOS 6 and the wireless package the legacy ones — SimpliFi picks the right commands from the reported version.
  • Router Access — Remote access turns on MikroTik DDNS (/ip cloud) and, on RouterOS 7.12+, the Back To Home VPN (add your phone in the MikroTik app). The cloud DNS name and WinBox address appear once the router reports them. With remote access on, SimpliFi support can reach the router through its cloud address when you ask for help.
  • Hotspot Configuration — Enable Hotspot (on), Hotspot Network 10.10.0.0/16, Gateway IP 10.10.0.1, DNS Servers 8.8.8.8,8.8.4.4, Hotspot Login URL = http:// + a name + a suffix. The default is wifi.<your-slug>.net: we avoid .local because Apple devices resolve .local names through mDNS and may skip the login page — .local stays selectable if you are used to it. Everything is validated: CIDR / IP / DNS formats, the gateway must be inside the network, and the network must not overlap your internet connection (the router told us its WAN subnet).
  • PPPoE (when you have PPPoE packages) — Enable PPPoE server on the LAN bridge with its IP pool (10.20.0.0/16). SimpliFi then creates, suspends and renews PPPoE accounts on this router.

Create pushes the configuration through Cloud Sync as an idempotent command set and shows Applying configuration…, ticking each item as the router acknowledges it: bridge ✓ · wireless ✓ · DHCP ✓ · hotspot ✓ · walled garden ✓ · packages ✓ · PPPoE ✓ · remote access ✓. What it installs: the bridge with your ports (and radios), the WiFi network, the router address + simplifi-pool + simplifi-dhcp + DNS + NAT masquerade, the SimpliFi hotspot pages (login.html, alogin.html, status.html, logout.html, error.html, rlogin.html, redirect.html, md5.js in simplifi/ or flash/simplifi/), the simplifi server profile (login-by=http-chap,http-pap,cookie,mac-cookie, your login name, use-radius=yes in RADIUS mode) and the hotspot server, the walled garden (your portal and SimpliFi hosts, Paystack, Hubtel, MTN MoMo, fonts — extend it with simplifi.mikrotik.walled_garden_hosts; MIKROTIK_SERVER_IP also allows your server IP), one hotspot user profile simplifi-<package id> per active package (plus the instant-activation pool), the PPPoE pool / profile / server / NAT, the RADIUS client (RADIUS mode) and /ip cloud. Everything is named or commented simplifi…. Re-running Create updates the router in place — nothing is ever duplicated. Turn Enable Hotspot off for a router that already runs a hotspot: SimpliFi then only points its profiles at the SimpliFi pages.

Done → next-step cards: Verify with a test voucher (the setup assistant's checklist: contact, health, hotspot pages, packages, walled garden and a free 10-minute test code), create packages, connect a payment gateway, SMS sender ID.


3. Direct API mode

  1. On the router create a dedicated user, e.g.
    /user group add name=simplifi policy=read,write,api,rest-api,test,!local,!telnet,!ssh,!ftp,!reboot,!policy,!password,!sniff,!sensitive,!romon
    /user add name=simplifi group=simplifi password="a long random password"
    
  2. Enable one service and allow only your SimpliFi server's IP:
    • REST (RouterOS 7, recommended): /ip service set www-ssl disabled=no address=<server-ip>/32 (needs a certificate: /certificate add name=simplifi common-name=router; /certificate sign simplifi then /ip service set www-ssl certificate=simplifi).
    • Classic API: /ip service set api-ssl disabled=no address=<server-ip>/32 (port 8729) or api (8728, unencrypted — only over a private link).
  3. In the wizard's step 01 open Advanced → Direct API: address, API type, port (blank = default), TLS and the user. Passwords are stored encrypted and never shown again — leave the field blank on edit to keep the saved one.
  4. Step 02: Test connection (SimpliFi also reads the interfaces). Step 03 is applied at once over the API (each block runs through a temporary /system script).

Self-signed router certificates are accepted (MIKROTIK_VERIFY_TLS=false, default), but they are pinned: on the first successful TLS connection SimpliFi remembers the router's public key (SHA-256, shown as "certificate remembered on …" in the wizard) and refuses any later connection that presents a different key, so an on-path attacker cannot impersonate the router afterwards. Replaced the certificate on purpose? Tick Forget the remembered certificate in step 01 and save. The classic API over TLS without a certificate uses anonymous DH ciphers; SimpliFi allows them via MIKROTIK_API_SSL_CIPHERS (default DEFAULT:ADH:@SECLEVEL=0) only until a key is pinned.

Router addresses must be public: loopback, link-local and (unless DEVICES_ALLOW_PRIVATE_HOSTS=true, for self-hosted installs on the routers' own network) private ranges are refused when saving and again when connecting.


4. Router page features

  • Live status (polls every few seconds until the first check-in) and a Finish setup / Setup wizard button.
  • Router changes: every queued change with its status (pending → sent → done / failed), Retry for failed or unconfirmed changes, Cancel for changes not sent yet.
  • Sync packages now: pushes all package profiles (and tops up the instant-activation pool).
  • Re-provision: re-applies the step-03 configuration (bridge, DHCP, hotspot pages, walled garden, profiles…) on the next check-in — idempotent. Re-run link script: re-imports the stage-1 script (identity, clock, sync scheduler).
  • Remote access: turns on MikroTik DDNS (/ip cloud) and, on RouterOS 7.12+ ARM / ARM64 routers, Back To Home VPN (add your phone in the MikroTik app). The cloud DNS name is shown once the router reports it.
  • Run a RouterOS script (owners and admins only, Cloud Sync / RADIUS): queued and run on the next check-in.
  • Regenerate setup command: the old link and the router's sync stop working at once; paste the new command on the router.
  • Instant activation pool: ready / syncing logins per package.

Speed: burst and fair use

Both come from the package (Packages → Advanced features) and are applied by this driver. The matrix in docs/VENDORS.md says which vendors can do them; MikroTik can do both in all three connection modes (Capability::BURST, Capability::FUP_THROTTLE).

The rate-limit string. RouterOS writes a speed as one positional string, used identically by /ip hotspot user profile, /ppp profile, /queue simple and the RADIUS attribute Mikrotik-Rate-Limit:

rx-rate[/tx-rate] [rx-burst-rate[/tx-burst-rate] [rx-burst-threshold[/tx-burst-threshold]
[rx-burst-time[/tx-burst-time] [priority [rx-rate-min[/tx-rate-min]]]]]]

rx is traffic the router receives = the customer's upload; tx is what it transmits = their download. Rates carry a k / M suffix, burst time is plain seconds, 0 means "no limit in this direction", and an empty string means "no limit at all". SimpliFi renders it in one place — App\Services\Routers\RateLimit, used by RouterOsScript::rateLimit() and RadiusRepository::rateLimit() — so the router and RADIUS can never disagree. What a 2 Mbps / 512 kbps package produces:

Package Rendered rate-limit
No speed set `` (empty: unlimited)
512 k up / 2048 k down 512k/2048k
Download only (2048 k) 0/2048k
+ burst 1024 k / 4096 k 512k/2048k 1024k/4096k
+ thresholds 768 k / 3072 k and 8 s 512k/2048k 1024k/4096k 768k/3072k 8/8
+ burst time 15 s, no thresholds 512k/2048k 1024k/4096k 512k/2048k 15/15

The fields are positional, so a burst time forces a threshold to be written; where none was entered SimpliFi writes the plan rate, which is exactly RouterOS's own default for it. A burst rate that is not faster than the plan (or an unlimited direction) is simply left out. Remember that burst-time is the period the average is taken over, not how long the burst lasts.

Fair-use policy (When allowance is reached → continue at reduced speed). /ip hotspot user has no rate-limit property of its own, and RouterOS 7 dropped it from /ppp secret, so a reduced rate has to come from a profile. Each throttling package therefore gets a second profile next to its own:

Profile Rate
Plan simplifi-<package id> (or the ISP's own router_profile) package speed + burst
Fair use simplifi-<package id>-fup (always SimpliFi's, never the ISP's) fup_upload_kbps/fup_download_kbps, no burst

syncPackage() (and Sync packages now) provisions both, so the reduced profile is already on the router before it is needed. When hotspot:expire / hotspot:usage sees a session past its allowance, App\Services\Hotspot\FupEnforcer calls applyFup() and this driver:

  • api — upserts the fair-use profile, sets the hotspot user's profile to it and limit-bytes-total=0 (the spent cap must not also cut the customer off), then removes the entry from /ip hotspot active;
  • cloud_sync — queues the same three steps as hotspot.profile.upsert, hotspot.user.upsert (reduced profile, no byte limit) and hotspot.active.kick;
  • radius — rewrites radreply (Mikrotik-Rate-Limit + WISPr, data-limit attributes removed) and queues hotspot.active.kick, because a RADIUS reply is only read at authentication and cPanel cannot send a CoA (docs/RADIUS.md).

The customer reconnects automatically. A profile's rate limit is read when the client logs in, so the live session has to be dropped; the device re-associates on its own and the MAC cookie (or its stored credentials) logs it straight back in, now on the reduced rate. The session itself stays active with its original expires_at — the customer paid for the time. The throttle is recorded in wifi_sessions.meta.fup and never undone: a later re-authorisation, Extend or pool tightening keeps the reduced profile and the lifted byte cap.

PPPoE usage, and fair use for a monthly plan

A PPPoE plan is a monthly subscription, so its allowance belongs to the period the customer paid for: renewing the plan starts the data again. SimpliFi therefore counts each subscriber's traffic per period (pppoe_accounts.bytes_in / bytes_out / session_seconds) and reads the counters from whichever source the router's connection mode provides. One source per router, so the same subscriber is never counted twice on two different scales:

Mode Where the counters come from How fresh
Cloud Sync the check-in's pp= field, every ~20 s seconds
Direct API pppoe:usage reads the router over the API 5 minutes
RADIUS pppoe:usage sums FreeRADIUS accounting (radacct) the NAS's interim-update interval (docs/RADIUS.md)

Why the interface counters. /ppp active tells us the name, address, uptime, caller-id and service of a live session but carries no byte counters (/ppp active). Every live PPPoE session does get its own dynamic interface (/interface pppoe-server: "Dynamic interfaces are added to this list automatically whenever a user is connected"), and that menu carries both the interface name and the subscriber user — so SimpliFi reads the pair there instead of guessing the <pppoe-USERNAME> naming, and takes rx-byte / tx-byte from /interface. As everywhere else, router rx = the customer's upload and tx = their download. Works the same on RouterOS 6.49+ and 7.x.

The list is posted in the same ~3 KB chunks as the hotspot users (final=0), and every block of the script is wrapped in :do / on-error, so a router with no PPPoE server simply reports an empty field.

Counting across re-dials. RouterOS starts the interface counters again at every re-dial, and radacct sums every accounting session ever stored. meta.counters therefore keeps base / last per counter — a reading lower than the last one means the counter restarted, so the previous reading is banked in base — plus a zero baseline captured the first time a source is read in a period. Whatever the router had already counted before SimpliFi first saw the session belongs to earlier periods: it is subtracted once, so nobody is billed for data from last month. PppoeAccount::resetUsagePeriod() (renewal, plan change, staff reset) drops the whole bookkeeping and the next reading starts the allowance again.

Online and offline. A check-in or poll that reports a subscriber refreshes last_seen_at; once nothing has reported them for Device::offlineAfterSeconds() (120 s, the same window a silent router gets) they count as offline.

Applying the reduced speed. When the counters cross the plan's allowance, pppoe:usage has FupEnforcer call applyFupToPppoe(), which moves the secret onto the package's simplifi-<id>-fup PPP profile and drops /ppp active — a PPPoE client re-dials by itself within seconds and comes back at the reduced rate. In RADIUS mode only radreply is rewritten and the session is not kicked: it applies at the next re-dial (docs/RADIUS.md). Applied once per period (fup_applied_at), marked only after the router accepted or queued the change, and never undone until the period is reset.

A "stop" package does not stop a PPPoE subscriber. fup_action = stop is meant for a prepaid hotspot session, not for a month the customer has paid for, so SimpliFi only enforces throttle packages here and leaves a "stop" plan to the normal expiry / suspension path (pppoe:enforce). Gear that cannot reduce a live PPP session leaves the customer at full speed and the reason is recorded in pppoe_accounts.meta.fup.message — SimpliFi never cuts a monthly subscriber off instead, and never pretends a change was made.

Load balancing

Devices → Load Balancing builds a PCC (per-connection classifier) multi-WAN script for 2–4 internet lines (DHCP, static or PPPoE) with weights, failover through recursive routes (check-gateway=ping, one public check host per line), NAT and an optional hotspot=auth filter. Copy it, download it, or Apply via Cloud Sync. Re-running replaces the previous simplifi-lb setup. RouterOS 6 uses routing marks, RouterOS 7 routing tables. Note: PCC does not work with strict reverse-path filtering (/ip settings rp-filter=strict).


5. Firewall and ports

Direction Port Needed for
Router → SimpliFi TCP 443 (HTTPS) Cloud Sync, link script, hotspot pages
Customers → portal / payments TCP 443 allowed before login by the walled garden
SimpliFi → router TCP 443 (REST) or 8728/8729 (API) Direct API mode only
Router → RADIUS UDP 1812/1813, RADIUS → router UDP 3799 RADIUS mode only

Cloud Sync needs no inbound ports. If you filter the router's output chain, allow HTTPS to your SimpliFi host. Throttling: 240 requests per minute per router by default (MIKROTIK_SYNC_RATE_LIMIT; each check-in posts the active-user list in ~3 KB chunks, about 40 users each, three times a minute).


6. How it works (developers)

  • Clients (app/Services/Routers/MikroTik/Api): RouterOsApiClient (binary protocol over stream_socket_client, length-prefixed words, !re/!done/!trap/!fatal/!empty, post-6.43 login), RouterOsRestClient (Laravel Http, explicit timeouts), RouterOsClientFactory (REST when credentials.api_type = rest or port 443/80, else binary).
  • Stage 1 (ProvisioningScriptBuilder::build(), served by api.devices.provision): identity, clock, simplifi-sync scheduler + script, first run. The sync script posts, besides health and users, the inventory (if=, br=, hs=, wan=, wanip=, wpkg=, dmode=) on every check-in; SyncPayload validates it and Setup\InventoryCollector stores it as devices.meta.inventory (Setup\RouterInventory). Direct API routers get the same inventory over the API when the connection is tested.
  • Wizard state (Setup\SetupState, column devices.wizard_state): connection (step 01), service (step 03), stage2.items (command ids per progress item), completed_at. progress() and isConfigured() are computed live from the command rows, so any browser shows the same ticks.
  • Stage 2 (Setup\ServiceSetupBuilder::items() → Setup\ServiceSetup::apply()): one device_command per item — setup.bridge, setup.wireless, setup.network, setup.radius, setup.hotspot, setup.walled_garden, setup.pppoe — plus the driver's hotspot.profile.upsert (packages + pool) and remote_access.*. CommandRenderer renders every block find-or-add (re-runs update in place), CommandQueue supersedes pending blocks of the same item, the router acks each block individually (api.devices.ack). Direct API routers run each block through a temporary /system script.
  • Cloud Sync (CloudSyncController, CloudSyncService): the router posts key=value lines. Active users (u=) and PPPoE subscribers (pp=user|rx-byte|tx-byte|uptime|address;) are sent in ≈3 KB chunks (final=0); the final=1 post updates the device (status, health, inventory, DeviceStatusChanged), the sessions (bytes, time used, online flags — router counters restart at every login, so drops are accumulated) and returns queued commands as a script the router /imports. pp= is applied by Usage\PppoeUsageRecorder for Cloud Sync routers only (a Direct API / RADIUS device has its own counter source), and the final post also marks the subscribers the router stopped reporting offline. Each command is compiled with :parse inside :do/on-error, so a missing menu or a bad command fails alone; the router then calls ack?ids=…&failed=….
  • Escaping (RouterOsScript::quote): every value is a double-quoted string with \, ", $ escaped, ? and control / non-ASCII bytes as \XX, newlines as \n — nothing in a payload can end the string or run a command. Interface and object names must additionally match CommandRenderer::NAME_PATTERN; ports are limited to what the router reported. Only script.run carries raw RouterOS code (owners/admins, or our own load-balancing generator). Snapshot tests (tests/Feature/MikroTik/StageScriptsSnapshotTest, __snapshots__/*.rsc) pin the stage-1 and stage-2 output on RouterOS 6.49 (wireless) and 7.x (wifi) — regenerate with UPDATE_SNAPSHOTS=1.
  • Voucher pool (VoucherPool): simplifi.mikrotik.pool_size (5) unused pool vouchers per active hotspot package per Cloud Sync router (vouchers.is_pool, pool_device_id), created as hotspot.user.upsert commands; the ack adds the router id to synced_device_ids. On payment, authorize() claims a confirmed one with a conditional UPDATE (never handed out twice), copies its code/password into the session, queues a tightening upsert (MAC lock, remaining time) and a refill. Without a confirmed pool login the user is queued and the portal's loginAction() answers wait until the router confirms (≤ 20 s).
  • Portal login: our login.html sends mac, ip, login, orig, cid, cch, err, username (CHAP id/challenge hex-encoded) to the device's portal URL. loginAction() redirects the browser to the router login URL with password = md5(chap-id . password . chap-challenge) (HTTP-CHAP; plain password when no CHAP data) and dst. Only the hotspot DNS name or a private / router IP is accepted as login URL.
  • Burst and fair use (RateLimit, PackageProfiles, MikroTikDriver::applyFup()): see §4 "Speed: burst and fair use" for the exact strings, the simplifi-<id>-fup profile and the per-mode behaviour. RateLimit is the single renderer for RouterOS and Mikrotik-Rate-Limit; sessionUserPayload() keeps a throttled session on the reduced profile with no byte cap, so a retry or Extend cannot hand the full speed back.
  • PPPoE usage (Usage\PppoeUsageRecorder, Usage\PppoeUsageMaintenance, Usage\RadiusUsageReader, MikroTikDriver::pppoeUsage(), FupEnforcer::enforcePppoeDue(), pppoe:usage every 5 minutes): see §4 "PPPoE usage, and fair use for a monthly plan" for the counter source per mode, the base / last / zero bookkeeping in meta.counters and why a "stop" package never disconnects a monthly subscriber.
  • Scheduler mikrotik:maintain (every minute): offline detection (120 s), re-delivery of unconfirmed commands, pool refill / prune, deletion of done commands after 7 days.
  • Setup assistant (M10) hand-over: the assistant's brand=mikrotik screens redirect to the wizard; steps / edit of a MikroTik router redirect to it too; the wizard's Done marks the assistant record verify and redirects to tenant.setup-assistant.verify, whose portal / walled_garden checks read Setup\SetupState.

References: hotspot user profile rate-limit (field order, defaults) — https://help.mikrotik.com/docs/spaces/ROS/pages/56459266/HotSpot+-+Captive+portal; Mikrotik-Rate-Limit worked example "64k/64k 256k/256k 128k/128k 10/10" — https://help.mikrotik.com/docs/spaces/ROS/pages/328097/RADIUS; burst rate / threshold / time semantics — https://help.mikrotik.com/docs/spaces/ROS/pages/328088/Queues; hotspot user and PPP properties (no rate-limit on either /ip hotspot user or /ppp secret) — https://manual.mikrotik.com/docs/cli-reference/ip/hotspot/user/, https://manual.mikrotik.com/docs/cli-reference/ppp/profile/; PPPoE usage: /ppp active has no byte counters — https://manual.mikrotik.com/docs/cli-reference/ppp/active/; the per-session dynamic interface and its user — https://manual.mikrotik.com/docs/cli-reference/interface/pppoe-server/; rx-byte / tx-byte — https://manual.mikrotik.com/docs/cli-reference/interface/; RouterOS API — https://help.mikrotik.com/docs/spaces/ROS/pages/47579160/API; REST API — https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST+API; hotspot customisation — https://manual.mikrotik.com/docs/7.25/authentication-authorization-accounting/hotspot-captive-portal/hotspot-customisation/; fetch — https://manual.mikrotik.com/docs/system-information-and-utilities/fetch; scripting — https://help.mikrotik.com/docs/spaces/ROS/pages/47579229/Scripting; WiFi (RouterOS 7) — https://help.mikrotik.com/docs/spaces/ROS/pages/1409149/WiFi; device-mode — https://help.mikrotik.com/docs/spaces/ROS/pages/93749258/Device-mode; Back To Home — https://manual.mikrotik.com/docs/7.25/network-management/cloud/back-to-home; load balancing — https://help.mikrotik.com/docs/spaces/ROS/pages/4390920/Load+Balancing.


7. Troubleshooting

Symptom Check
Step 02 stays on “Attempt N of 300” On the router: /ping 8.8.8.8, /ping google.com (DNS), /log print where message~"SimpliFi". Is the clock right? Device-mode (RouterOS 7.17+)? Paste the command again.
“failure: … SSL” / fetch errors on RouterOS 6 Upgrade to the latest 6.49.x or to 7.x (old TLS). One-time fallback: mode=http.
“not allowed by device-mode” /system/device-mode update mode=advanced, power off 10 s, power on, paste again.
Router went offline in SimpliFi It has not checked in for 2 minutes. Check its internet, then /system scheduler print (is simplifi-sync enabled?). If the setup command was regenerated, paste the new one.
A configuration item shows failed in step 03 The router rejected that block — see the router log for “SimpliFi: command N failed”. Fix the cause (usually a port that no longer exists or an address in use) and press Create again.
A change shows failed on the router page The router rejected it — see the router log. Fix the cause and Retry.
Customers are not redirected to the portal /ip hotspot print (server on bridge-hotspot?), /ip hotspot profile print (html-directory=simplifi), walled garden contains your portal host. Access points must be in bridge/AP mode on a ticked port.
iPhones skip the login page The login name ends in .local — change the suffix in step 03 and press Create again.
Payment page does not load before login Add the payment host to simplifi.mikrotik.walled_garden_hosts and Re-provision.
“Activating your access…” takes long The router checks in every 20 s; check its status. Instant activation needs a ready pool (router page → Instant activation pool).
Direct API: “Login failed” User/password, the user group needs api (classic) or rest-api (REST), service address list allows your server.
Logs fill with fetch messages Normal for Cloud Sync. Hide them with /system logging set [find topics~"info"] topics=info,!fetch if you like.

Remove SimpliFi from a router: delete the simplifi-sync scheduler and script, the simplifi hotspot profile / server / simplifi-pool / simplifi-dhcp, bridge-hotspot (move the ports back), walled-garden entries commented simplifi, user profiles named simplifi-*, the simplifi wireless security profile and the simplifi-pppoe pool / profile / server.

Ready to try it on your network?

Start your 14-day free trial today. Set up in minutes, no credit card, cancel any time.

Install SimpliFi App

One tap, no app store. Faster, full screen, works on weak signal.