Imported from LeoYeAI/openclaw-master-skills (skills/mikrotik-api/SKILL.md). Install upstream with npx skills add LeoYeAI/openclaw-master-skills --skill mikrotik-api. Copyright stays with the author.
MikroTik API Management
Communicate with MikroTik RouterOS devices using the Python routeros-api library over the API port (8728 plain, 8729 SSL).
Prerequisites
Install the library if not present:
pip3 install --break-system-packages routeros-api
Connection
It is highly recommended to use environment variables for credentials to avoid hardcoding.
Environment Variables
Set these in your environment or .env file:
MIKROTIK_HOST: Router IP or hostname
MIKROTIK_USERNAME: Router username
MIKROTIK_PASSWORD: Router password
Python Connection Pattern
import routeros_api
import os
# Get credentials from environment variables
host = os.getenv('MIKROTIK_HOST')
username = os.getenv('MIKROTIK_USERNAME')
password = os.getenv('MIKROTIK_PASSWORD')
# Fallback to manual input if env vars are missing
if not all([host, username, password]):
print("Environment variables MIKROTIK_HOST, MIKROTIK_USERNAME, or MIKROTIK_PASSWORD are not set.")
# host = input("Enter Host: ") ...
conn = routeros_api.RouterOsApiPool(
host=host,
username=username,
password=password,
plaintext_login=True, # Required for RouterOS 6.43+
port=8728 # Use 8729 for SSL
)
api = conn.get_api()
# ... do work ...
conn.disconnect()
Connection Rules
- Prefer Environment Variables: Instruct the user to set
MIKROTIK_HOST, MIKROTIK_USERNAME, and MIKROTIK_PASSWORD.
- Ask the user for these details only if not found in the environment.
- Default API port is 8728 (plain) or 8729 (SSL).
- Always call
conn.disconnect() when done.
- Use
plaintext_login=True for RouterOS v6.43+ and v7.x.
SSL Connection
conn = routeros_api.RouterOsApiPool(
host=host,
username=username,
password=password,
plaintext_login=True,
use_ssl=True,
ssl_verify=False, # Set True with proper certs
ssl_verify_hostname=False,
port=8729
)
Core API Operations
Reading resources (GET / print)
resource = api.get_resource('/ip/address')
items = resource.get() # Get all
items = resource.get(interface='ether1') # Filter by param
items = resource.get(disabled='false') # Filter by status
Adding entries (ADD)
resource = api.get_resource('/ip/address')
resource.add(address='192.168.1.1/24', interface='ether1')
# With comment
resource.add(address='192.168.1.1/24', interface='ether1', comment='Management')
Updating entries (SET)
resource = api.get_resource('/ip/address')
resource.set(id='*1', address='192.168.2.1/24')
resource.set(id='*1', comment='Updated via API')
resource.set(id='*1', disabled='yes') # Disable entry
resource.set(id='*1', disabled='no') # Enable entry
Removing entries (REMOVE)
resource.remove(id='*1')
Calling commands (CALL)
resource = api.get_resource('/system')
resource.call('reboot')
# Call with parameters
resource = api.get_resource('/ip/firewall/filter')
resource.call('move', {'numbers': '*1', 'destination': '*5'})
Enabling / Disabling entries
resource = api.get_resource('/interface')
resource.set(id='*1', disabled='yes') # Disable
resource.set(id='*1', disabled='no') # Enable
Complete Resource Path Reference
System
| Task |
Resource Path |
| System info (CPU, RAM, uptime) |
/system/resource |
| Router identity |
/system/identity |
| System clock |
/system/clock |
| NTP client |
/system/ntp/client |
| NTP server |
/system/ntp/server |
| Scheduler |
/system/scheduler |
| Scripts |
/system/script |
| Logging rules |
/system/logging |
| Log entries |
/log |
| Packages |
/system/package |
| Package update |
/system/package/update |
| Router board info |
/system/routerboard |
| License |
/system/license |
| Health (voltage, temp) |
/system/health |
| History |
/system/history |
| Users |
/user |
| User groups |
/user/group |
| Active users |
/user/active |
| SSH keys |
/user/ssh-keys |
| Files |
/file |
| Backup |
/system/backup |
| SNMP |
/snmp |
| SNMP community |
/snmp/community |
| Certificates |
/certificate |
| Console |
/system/console |
| LEDs |
/system/leds |
Interfaces
| Task |
Resource Path |
| All interfaces |
/interface |
| Ethernet |
/interface/ethernet |
| Bridge |
/interface/bridge |
| Bridge ports |
/interface/bridge/port |
| Bridge VLANs |
/interface/bridge/vlan |
| Bridge hosts (MAC table) |
/interface/bridge/host |
| Bridge MSTi |
/interface/bridge/msti |
| Bridge settings |
/interface/bridge/settings |
| VLAN |
/interface/vlan |
| Bonding (LACP/bonding) |
/interface/bonding |
| EoIP tunnel |
/interface/eoip |
| GRE tunnel |
/interface/gre |
| IPIP tunnel |
/interface/ipip |
| VXLAN |
/interface/vxlan |
| VXLAN VTEP |
/interface/vxlan/vtep |
| WireGuard |
/interface/wireguard |
| WireGuard peers |
/interface/wireguard/peers |
| L2TP client |
/interface/l2tp-client |
| L2TP server |
/interface/l2tp-server/server |
| SSTP client |
/interface/sstp-client |
| SSTP server |
/interface/sstp-server/server |
| OVPN client |
/interface/ovpn-client |
| OVPN server |
/interface/ovpn-server/server |
| PPPoE client |
/interface/pppoe-client |
| PPPoE server |
/interface/pppoe-server/server |
| PPTP client |
/interface/pptp-client |
| PPTP server |
/interface/pptp-server/server |
| LTE |
/interface/lte |
| LTE APN |
/interface/lte/apn |
| Wireless (WiFi legacy) |
/interface/wireless |
| WiFi (new, ROS 7) |
/interface/wifi |
| WiFi channels |
/interface/wifi/channel |
| WiFi datapath |
/interface/wifi/datapath |
| WiFi security |
/interface/wifi/security |
| WiFi configuration |
/interface/wifi/configuration |
| WiFi provisioning |
/interface/wifi/provisioning |
| WiFi registration table |
/interface/wifi/registration-table |
| WiFi access list |
/interface/wifi/access-list |
| WiFi interworking |
/interface/wifi/interworking |
| Interface lists |
/interface/list |
| Interface list members |
/interface/list/member |
| Ethernet switch |
/interface/ethernet/switch |
| Ethernet switch port |
/interface/ethernet/switch/port |
| Traffic monitor |
/interface/monitor-traffic |
IP
| Task |
Resource Path |
| IP addresses |
/ip/address |
| ARP table |
/ip/arp |
| Routes |
/ip/route |
| Route rules |
/ip/route/rule |
| DNS settings |
/ip/dns |
| DNS static entries |
/ip/dns/static |
| DNS cache |
/ip/dns/cache |
| DHCP client |
/ip/dhcp-client |
| DHCP server |
/ip/dhcp-server |
| DHCP server network |
/ip/dhcp-server/network |
| DHCP server leases |
/ip/dhcp-server/lease |
| DHCP server option |
/ip/dhcp-server/option |
| DHCP server option sets |
/ip/dhcp-server/option/sets |
| DHCP relay |
/ip/dhcp-relay |
| IP pool |
/ip/pool |
| IP neighbors |
/ip/neighbor |
| IP neighbor discovery |
/ip/neighbor/discovery-settings |
| IP services |
/ip/service |
| IP settings (forwarding) |
/ip/settings |
| IP proxy |
/ip/proxy |
| IP proxy access list |
/ip/proxy/access |
| IP SOCKS |
/ip/socks |
| IP SSH |
/ip/ssh |
| IP cloud |
/ip/cloud |
| IP UPnP |
/ip/upnp |
| IP UPnP interfaces |
/ip/upnp/interfaces |
| IP SMB |
/ip/smb |
| IP traffic flow |
/ip/traffic-flow |
| IP traffic flow target |
/ip/traffic-flow/target |
| IP accounting |
/ip/accounting |
| IP Kid Control |
/ip/kid-control |
| IP Kid Control devices |
/ip/kid-control/device |
| IP Hotspot |
/ip/hotspot |
| IP Hotspot profile |
/ip/hotspot/profile |
| IP Hotspot user |
/ip/hotspot/user |
| IP Hotspot user profile |
/ip/hotspot/user/profile |
| IP Hotspot active |
/ip/hotspot/active |
| IP Hotspot host |
/ip/hotspot/host |
| IP Hotspot cookie |
/ip/hotspot/cookie |
| IP Hotspot IP binding |
/ip/hotspot/ip-binding |
| IP Hotspot walled garden |
/ip/hotspot/walled-garden |
| IP Hotspot walled garden IP |
/ip/hotspot/walled-garden/ip |
Firewall
| Task |
Resource Path |
| Filter rules |
/ip/firewall/filter |
| NAT rules |
/ip/firewall/nat |
| Mangle rules |
/ip/firewall/mangle |
| RAW rules |
/ip/firewall/raw |
| Address lists |
/ip/firewall/address-list |
| Connections (conntrack) |
/ip/firewall/connection |
| Connection tracking |
/ip/firewall/connection/tracking |
| Service ports (ALGs) |
/ip/firewall/service-port |
| Layer 7 protocols |
/ip/firewall/layer7-protocol |
IPv6
| Task |
Resource Path |
| IPv6 addresses |
/ipv6/address |
| IPv6 routes |
/ipv6/route |
| IPv6 firewall filter |
/ipv6/firewall/filter |
| IPv6 firewall mangle |
/ipv6/firewall/mangle |
| IPv6 firewall RAW |
/ipv6/firewall/raw |
| IPv6 firewall address list |
/ipv6/firewall/address-list |
| IPv6 ND (Neighbor Disc.) |
/ipv6/nd |
| IPv6 ND prefix |
/ipv6/nd/prefix |
| IPv6 DHCP client |
/ipv6/dhcp-client |
| IPv6 DHCP server |
/ipv6/dhcp-server |
| IPv6 pool |
/ipv6/pool |
| IPv6 settings |
/ipv6/settings |
Routing (RouterOS 7)
| Task |
Resource Path |
| Routing tables |
/routing/table |
| Routing rules |
/routing/rule |
| OSPF instance |
/routing/ospf/instance |
| OSPF area |
/routing/ospf/area |
| OSPF interface template |
/routing/ospf/interface-template |
| OSPF neighbors |
/routing/ospf/neighbor |
| OSPF LSA |
/routing/ospf/lsa |
| BGP connection |
/routing/bgp/connection |
| BGP template |
/routing/bgp/template |
| BGP session |
/routing/bgp/session |
| BGP advertisements |
/routing/bgp/advertisements |
| BGP networks |
/routing/bgp/network |
| RIP instance |
/routing/rip/instance |
| RIP interface template |
/routing/rip/interface-template |
| Route filter rules |
/routing/filter/rule |
| Route filter select rules |
/routing/filter/select-rule |
| Prefix lists |
/routing/filter/community-list |
| BFD session |
/routing/bfd/session |
| BFD configuration |
/routing/bfd/configuration |
| Routing ID |
/routing/id |
| RPKI |
/routing/rpki |
| IGMP Proxy |
/routing/igmp-proxy |
| PIM |
/routing/pimsm |
PPP
| Task |
Resource Path |
| PPP secrets |
/ppp/secret |
| PPP profiles |
/ppp/profile |
| PPP active connections |
/ppp/active |
| PPP AAA settings |
/ppp/aaa |
| PPP L2TP secret |
/ppp/l2tp-secret |
Queues (QoS)
| Task |
Resource Path |
| Simple queues |
/queue/simple |
| Queue tree |
/queue/tree |
| Queue types |
/queue/type |
| Interface queues |
/queue/interface |
CAPsMAN / WiFi Controller (ROS 7)
| Task |
Resource Path |
| CAPsMAN manager |
/caps-man/manager |
| CAPsMAN configuration |
/caps-man/configuration |
| CAPsMAN channel |
/caps-man/channel |
| CAPsMAN datapath |
/caps-man/datapath |
| CAPsMAN security |
/caps-man/security |
| CAPsMAN provisioning |
/caps-man/provisioning |
| CAPsMAN interface |
/caps-man/interface |
| CAPsMAN registration table |
/caps-man/registration-table |
| CAPsMAN access list |
/caps-man/access-list |
| CAPsMAN remote-cap |
/caps-man/remote-cap |
MPLS
| Task |
Resource Path |
| MPLS settings |
/mpls |
| MPLS interface |
/mpls/interface |
| MPLS forwarding table |
/mpls/forwarding-table |
| MPLS LDP |
/mpls/ldp |
| MPLS LDP interface |
/mpls/ldp/interface |
| MPLS LDP neighbor |
/mpls/ldp/neighbor |
| VPLS |
/interface/vpls |
| Traffic engineering |
/mpls/traffic-eng |
Tools
| Task |
Resource Path |
| Ping |
/tool/ping (use call) |
| Traceroute |
/tool/traceroute (use call) |
| Bandwidth test |
/tool/bandwidth-test (use call) |
| Torch (traffic by IP) |
/tool/torch (use call) |
| Profile (CPU profile) |
/tool/profile |
| Netwatch |
/tool/netwatch |
| E-mail settings |
/tool/e-mail |
| Fetch (HTTP client) |
/tool/fetch |
| Graphing interface |
/tool/graphing/interface |
| Graphing resource |
/tool/graphing/resource |
| Graphing queue |
/tool/graphing/queue |
| Sniffer |
/tool/sniffer |
| SNMP |
/snmp |
| MAC server |
/tool/mac-server |
| MAC Winbox |
/tool/mac-server/mac-winbox |
| MAC Ping |
/tool/mac-server/ping |
| Bandwidth server |
/tool/bandwidth-server |
| IP Scan |
/tool/ip-scan |
| SMS |
/tool/sms |
| Romon |
/tool/romon |
Container (ROS 7.4+)
| Task |
Resource Path |
| Container config |
/container/config |
| Containers |
/container |
| Container mounts |
/container/mounts |
| Container envs |
/container/envs |
IoT
| Task |
Resource Path |
| IoT Bluetooth |
/iot/bluetooth |
| IoT Bluetooth scanners |
/iot/bluetooth/scanners |
| IoT GPIO |
/iot/gpio |
| IoT MQTT broker |
/iot/mqtt/brokers |
ZeroTier
| Task |
Resource Path |
| ZeroTier |
/zerotier |
| ZeroTier interface |
/zerotier/interface |
Advanced Operations
Filtering with multiple parameters
resource = api.get_resource('/ip/firewall/filter')
rules = resource.get(chain='forward', action='drop')
Ordering firewall rules (place-before)
resource = api.get_resource('/ip/firewall/filter')
resource.add(
chain='forward',
action='accept',
src_address='10.0.0.0/8',
place_before='*5' # Insert before rule *5
)
Note: Use underscores in Python for hyphenated attributes (e.g., src-address → src_address, place-before → place_before).
Moving firewall rules
resource = api.get_resource('/ip/firewall/filter')
resource.call('move', {'numbers': '*A', 'destination': '*1'})
Batch operations
resource = api.get_resource('/ip/firewall/address-list')
ips = ['1.2.3.4', '5.6.7.8', '9.10.11.12']
for ip in ips:
resource.add(list='blocklist', address=ip, comment='Blocked via API')
Enable/disable by name
resource = api.get_resource('/interface')
ifaces = resource.get(name='ether5')
if ifaces:
resource.set(id=ifaces[0]['id'], disabled='yes')
Get specific properties only
# The library always returns all properties; filter in Python:
resource = api.get_resource('/interface')
for iface in resource.get():
print(iface.get('name'), iface.get('type'), iface.get('running'))
Run system tools (ping, traceroute)
# Tools that produce output need call() with parameters
resource = api.get_resource('/tool')
# Note: Some tools (ping, traceroute) run indefinitely.
# Use count parameter to limit.
result = resource.call('ping', {'address': '8.8.8.8', 'count': '4'})
for r in result:
print(r)
Backup & Export
# Create a backup file
resource = api.get_resource('/system/backup')
resource.call('save', {'name': 'api-backup'})
# Export config to file
resource = api.get_resource('/')
resource.call('export', {'file': 'api-export'})
System reboot / shutdown
resource = api.get_resource('/system')
resource.call('reboot')
# resource.call('shutdown')
Firmware / Package update
resource = api.get_resource('/system/package/update')
resource.call('check-for-updates')
result = resource.get()
print(result)
# resource.call('install') # Install and reboot
REST API (RouterOS 7.1+)
RouterOS 7.1+ also supports a REST API over HTTP/HTTPS. Use when the Python library is unavailable.
REST via curl
# GET - Read resources
curl -k -u user:pass https://<IP>/rest/ip/address
# PUT - Create new entry
curl -k -u user:pass -X PUT https://<IP>/rest/ip/address \
--data '{"address":"192.168.1.1/24","interface":"ether1"}' \
-H "content-type: application/json"
# PATCH - Update entry
curl -k -u user:pass -X PATCH https://<IP>/rest/ip/address/*1 \
--data '{"comment":"updated"}' -H "content-type: application/json"
# DELETE - Remove entry
curl -k -u user:pass -X DELETE https://<IP>/rest/ip/address/*1
# POST - Run any command
curl -k -u user:pass -X POST https://<IP>/rest/ip/address/print \
--data '{"_proplist":["address","interface"]}' \
-H "content-type: application/json"
REST with query filters
curl -k -u user:pass -X POST https://<IP>/rest/interface/print \
--data '{".query":["type=ether"],"_proplist":["name","type","running"]}' \
-H "content-type: application/json"
REST via Python requests
import requests
from requests.auth import HTTPBasicAuth
base = 'https://<IP>/rest'
auth = HTTPBasicAuth('<USER>', '<PASS>')
# GET all interfaces
r = requests.get(f'{base}/interface', auth=auth, verify=False)
print(r.json())
# POST (run commands with parameters)
r = requests.post(f'{base}/ip/address/print',
auth=auth, verify=False,
json={'_proplist': ['address', 'interface']})
print(r.json())
Error Handling
import routeros_api
from routeros_api.exceptions import RouterOsApiCommunicationError
try:
conn = routeros_api.RouterOsApiPool(host, username=user, password=pw, plaintext_login=True)
api = conn.get_api()
resource = api.get_resource('/ip/address')
resource.add(address='invalid', interface='nonexistent')
except RouterOsApiCommunicationError as e:
print(f"API Error: {e}")
except ConnectionError:
print("Cannot reach router")
finally:
try:
conn.disconnect()
except:
pass
API Error Categories
| Code |
Meaning |
| 0 |
Missing item or command |
| 1 |
Argument value failure |
| 2 |
Command interrupted |
| 3 |
Scripting related failure |
| 4 |
General failure |
| 5 |
API related failure |
| 6 |
TTY related failure |
| 7 |
Value from :return command |
Workflow
- Connect to the router using credentials from environment variables or the user.
- Read first — always fetch current state before making changes.
- Confirm destructive operations (delete, disable, reboot, firewall changes) with the user.
- Apply changes using add/set/remove.
- Verify by reading back the resource after changes.
- Disconnect when done.
Important Notes
- The
id field in responses (e.g., *1, *A) is the internal MikroTik ID used for set/remove.
- Use underscore in Python kwargs for hyphenated RouterOS attributes:
src-address → src_address.
- Filter and NAT rules are order-sensitive — use
place_before when adding to control position.
- Always show the user what currently exists before modifying firewall rules.
- For bulk operations, iterate over results and apply changes one by one.
- RouterOS 7.x uses different paths for routing (e.g.,
/routing/ospf/instance not /routing/ospf).
- If the API port is closed, advise the user to enable it:
/ip/service enable api.
- Tools like ping/traceroute run indefinitely — always pass
count or duration parameter.
- REST API requires
www or www-ssl service enabled on the router.
- REST API has a 60-second timeout for commands; use limiting params (
count, duration, once).