FyberPay communicates with MikroTik routers via the RouterOS REST API, introduced in RouterOS 7.1. For RouterOS 6.x devices, FyberPay uses the legacy API port. Each router connects over an encrypted SSTP management tunnel, so the API is never exposed to the public internet.Documentation Index
Fetch the complete documentation index at: https://docs.fyberpay.com/llms.txt
Use this file to discover all available pages before exploring further.
Supported RouterOS Versions
| Version | API Method | Notes |
|---|---|---|
| RouterOS 7.1+ | REST API (HTTP/HTTPS) | Recommended. Full feature support. |
| RouterOS 6.x | REST API via www service | Requires /ip service set www enabled. |
/rest/ endpoint prefix for all API calls, which requires the www or www-ssl service to be enabled on the router.Architecture Overview
Connection Setup
Register the NAS device
- Device name: a human-readable label (e.g. “Westlands-POP-1”)
- IP address: the router’s WAN IP (used for RADIUS NAS registration)
- RADIUS secret: shared secret for RADIUS authentication
- CoA port: default is
3799
Run the bootstrap script
BOOTSTRAP_VERSION=2, current) is tunnel-first: it brings the SSTP management tunnel up before touching anything else, so a partial bootstrap leaves the router reachable for retry. Steps:- SSTP tunnel creation with a dedicated PPP profile (
fyberpay-tunnel) - RADIUS client configuration (authentication port 1812, accounting port 1813)
- REST API user creation with scoped permissions
- Firewall rules to allow tunnel traffic, ordered so the tunnel rule lands first
comment=FyberPay-fw:*); the operator’s hand-rolled firewall is never modified.Configure the REST API user
fyberpay-api. This group has the following policies:ftp, reboot, policy, test, password, sniff, sensitive, romon.The REST API service is restricted to the tunnel subnet:API Port Configuration
| Port | Protocol | Use Case |
|---|---|---|
| 80 | HTTP | Default REST API port over SSTP tunnel |
| 443 | HTTPS | REST API with TLS (self-signed certs accepted) |
| 8728 | API | Legacy MikroTik API protocol (RouterOS 6.x) |
| 8729 | API-SSL | Legacy API with TLS |
What FyberPay Reads from the Router
FyberPay polls the following data from each connected router:System Resources
System Resources
GET /rest/system/resourceRetrieves CPU load, memory usage (total/free), uptime, RouterOS version, board name, and architecture. Displayed on the fleet dashboard.Active PPP Sessions
Active PPP Sessions
GET /rest/ppp/activeLists all active PPPoE/PPTP/L2TP sessions with username, service type, caller ID, assigned IP, uptime, and encoding. Used for subscriber session monitoring.Network Interfaces
Network Interfaces
GET /rest/interfaceReturns all interfaces with name, type, running/disabled status, TX/RX byte counters, packet counts, link-down count, and MTU.DHCP Leases
DHCP Leases
GET /rest/ip/dhcp-server/leaseLists active DHCP leases with IP address, MAC address, hostname, status, and expiry time.Simple Queues
Simple Queues
GET /rest/queue/simpleReads all simple queues with name, target address, max-limit, and burst-limit. Used for bandwidth plan enforcement visibility.PPPoE Servers
PPPoE Servers
GET /rest/interface/pppoe-server/serverLists configured PPPoE server instances with service name, bound interface, and disabled state.What FyberPay Writes to the Router
FyberPay’s writes to the router are driven by the NasService model: one row per customer-facing service (PPPoE, Hotspot, or CPE Management), reconciled against live router state by the NasService Reconciler. Operators create services in the FyberPay admin UI; the reconciler translates each service into the right combination of PPPoE servers, hotspot servers, IP addresses, pools, DHCP, VLAN sub-interfaces, walled-garden rules, and bridges on the live router.The NasService model
Each service is one row in thenas_services table with these fields:
| Field | Meaning |
|---|---|
type | pppoe, hotspot, or cpe-management |
parentInterface | The interface on the router the service binds to. Can be an ether port (ether2), an SFP port (sfp1), a VLAN sub-interface (vlan100-mgmt), or an operator-managed bridge (bridge-customer). |
vlanId | Optional VLAN tag. If set, the reconciler creates a VLAN sub-interface as the binding point. |
subnet, gateway, poolStart, poolEnd | Auto-allocated from 10.50.0.0/16 (customer) or 10.20.0.0/16 (management). Operator can override under “Advanced”. |
state | pending → active (or failed / degraded if the reconciler hits an error or detects drift). |
5d8f2a1e-... is named pppoe-svc-5d8f2a1e. Every resource the reconciler creates carries comment=FyberPay-svc:<service-id> so ownership is unambiguous on the router.
The reconciler primitives
Three idempotent primitives, all inapps/api/src/network/nas-services/reconciler.ts:
- applyService(serviceId): read live state for the service tag, compute a diff against the desired state, execute the diff. Used on create, update, manual reconcile, and drift recovery.
- removeService(serviceId): tear down every resource carrying the service tag. Used on delete.
- reconcileDevice(deviceId): scan the device for orphaned resources (carrying a service tag for a service that no longer exists in the database) and remove them.
Bridge as parent interface
If the operator already runs a downstream switch off their MikroTik and wants every customer plugged into any LAN port to use the same service, they create a bridge on the router and pick that bridge as the parent interface. See the bridge-as-parent guide for the full operator workflow. The parent-interface dropdown groups options by type (Bridges, Ethernet, SFP, VLAN). Bridges are filtered to excludebridge, bridge-lan, fyberpay-tunnel, and any FyberPay-managed br-svc-* bridge (those are reserved by the reconciler itself). VLAN-on-bridge is allowed for tagged trunks.
Reserved interfaces (safety guard)
Before any RouterOS write, the reconciler checks the parent interface against a reserved set computed live from the router. The reserved set is the union of seven sources:- Always-reserved names:
bridge,bridge-lan,fyberpay-tunnel - Members of
bridge-lan(the management LAN) - Interfaces with a bound DHCP client (the WAN uplink)
- Interfaces a default route exits through
- Members of the RouterOS
WANinterface-list, if the operator set one - PPPoE/L2TP/SSTP client interfaces (the router dialing out to its upstream)
- FyberPay-managed service-scoped bridges (
br-svc-*) — identified by their service-tag comment
Drift detection
A BullMQ background job runs every ~15 minutes per device. For each NasService, it computes the diff between the live router state and the desired state. If the diff is non-empty, the service is markeddegraded and an outbox event (nas.service.drift_detected) is emitted.
Drift detection is detect-only by default. The operator clicks Reconcile on the service card to apply the diff. Auto-healing is intentionally not on by default to avoid silently undoing deliberate operator changes made in Winbox.
Reconfigure semantics (hard cut)
When an operator changes a service’stype, parentInterface, or vlanId, the reconciler tears down the old resources and creates new ones. Active customer sessions on the affected service are kicked. The UI surfaces a confirmation dialog quoting the impact (“This will disconnect N active users. Re-issue with confirm=true to proceed.”) before allowing the change.
Non-disruptive changes (subnet/gateway/pool tweaks, walled-garden adjustments) apply without kicking sessions.
Other writes
Walled garden (hotspot)
Walled garden (hotspot)
PUT /rest/ip/hotspot/walled-garden
IPs: PUT /rest/ip/hotspot/walled-garden/ipEach hotspot service maintains its own walled-garden rules (Safaricom Daraja endpoints, FyberPay’s payment callback domain, M-Pesa portal). Operators can add custom entries per service.Firewall Address Lists
Firewall Address Lists
PUT /rest/ip/firewall/address-list
Remove entry: DELETE /rest/ip/firewall/address-list/{id}Used for walled-garden enforcement on the L3 path (post-dunning subscribers redirected to a “pay your bill” portal until they pay).Simple Queue Updates
Simple Queue Updates
PATCH /rest/queue/simple/{id}Optional. Used when an ISP manages bandwidth through router-side queues rather than RADIUS attributes (the recommended path is RADIUS-driven via FreeRADIUS, see the FreeRADIUS integration).Device Reboot
Device Reboot
POST /rest/system/rebootTriggers a remote reboot. Requires admin or super_admin role. All reboot actions are recorded in the audit log.What FyberPay does NOT manage on the router
- WAN configuration: never touched. WAN is detected (sources 3/4/5/6 of the reserved set) and protected.
- Operator-managed bridges: their existence and port membership are owned by the operator. FyberPay binds to bridges but never modifies their members or comments.
- Default firewall: never touched. The bootstrap script only adds tunnel-traffic allow rules.
- Existing PPP profiles: never touched. FyberPay creates per-service profiles named
ppp-prof-svc-<slug>.
Fleet Monitoring
FyberPay polls all configured NAS devices in parallel (batches of 10) to build the fleet status dashboard. Each device reports:- Reachability (online/offline)
- Board name and RouterOS version
- CPU load percentage
- Memory usage percentage
- System uptime
- Active PPP session count
RADIUS Configuration
The bootstrap script configures each router as a RADIUS client pointing to FyberPay’s FreeRADIUS server:Troubleshooting
Router shows as unreachable
Router shows as unreachable
- Verify the SSTP tunnel is established: check
/interface sstp-client printon the router - Confirm the tunnel has an IP in the 10.99.x.x range:
/ip address print where interface=fyberpay-tunnel - Ensure the
wwwservice is enabled and bound to the tunnel subnet:/ip service print - Check that the firewall allows tunnel traffic:
/ip firewall filter print where comment~"FyberPay"
API credentials not configured error
API credentials not configured error
SSTP tunnel keeps disconnecting
SSTP tunnel keeps disconnecting
- Confirm the tunnel uses
profile=fyberpay-tunnel(notprofile=default) - Check that
verify-server-certificate=nois set (FyberPay uses self-signed certs for the SSTP server) - Verify the router has stable internet connectivity:
/ping 8.8.8.8 count=5 - Review tunnel logs:
/log print where topics~"sstp"
REST API returns 401 Unauthorized
REST API returns 401 Unauthorized
Circuit breaker is open
Circuit breaker is open
A service stays in 'pending' state forever
A service stays in 'pending' state forever
- Parent interface no longer exists (renamed or deleted in Winbox)
- Parent interface has its own IP that conflicts with the service’s allocated subnet
- A bridge member port has its own
/ip/address(RouterOS won’t allow it as a bridge port) - The router is unreachable (circuit breaker open)
A service shows 'degraded' state
A service shows 'degraded' state
- An operator manually deleted the PPPoE/hotspot server in Winbox
- The router was reset to defaults but FyberPay’s NasService row still exists
- Someone modified a FyberPay-managed resource without going through the FyberPay UI
The bridge I created in Winbox does not appear in the parent-interface picker
The bridge I created in Winbox does not appear in the parent-interface picker
- The bridge is disabled. Run
/interface/bridge enable <name>on the router. - The bridge name is
bridge,bridge-lan, orfyberpay-tunnel(always-reserved). - The bridge’s comment carries a FyberPay service tag (
FyberPay-svc:...). Either you accidentally edited an existingbr-svc-*bridge’s comment, or this is a FyberPay-managed bridge. Pick a different bridge with a different name. - The router is unreachable, so FyberPay cannot list its interfaces.
Security Considerations
- All API traffic flows through the encrypted SSTP tunnel. No RouterOS API ports are exposed on public interfaces.
- API credentials are encrypted at rest using AES-256 (the platform
ENCRYPTION_KEY). - The
fyberpay-apiuser group has minimal permissions: no access topolicy,password,sensitive, orsniffoperations. - Every write operation (reboot, queue change, address list modification) is recorded in FyberPay’s audit log with the acting user, timestamp, and IP address.