Go client library for MikroTik RouterOS. Supports both the REST API (RouterOS v7+) and the API Protocol (RouterOS v6 & v7). Tested on real hardware with full TLS support.
| RouterOS | Version | API (8728) | API-SSL (8729) | REST HTTP (80) | REST HTTPS (443) |
|---|---|---|---|---|---|
| v7 | 7.15 (stable) | ✅ | ✅ | ✅ | ✅ |
| v6 | 6.49.19 (long-term) | ✅ | ✅ | — | — |
go get github.com/Cepat-Kilat-Teknologi/go-routerosRequires Go 1.21 or later.
| Package | Protocol | Transport | Port | RouterOS Version |
|---|---|---|---|---|
rest |
REST API | HTTP/HTTPS | 80/443 | v7 only |
api |
API Protocol | TCP/TLS | 8728/8729 | v6 & v7 |
- RouterOS v6 → Use
api(REST API is not available in v6) - RouterOS v7, simple CRUD → Use
rest(simpler HTTP-based approach) - RouterOS v7, advanced features → Use
api(more powerful query filtering, future streaming/listen support)
Both packages follow the same design patterns (functional options, typed errors, context support), so switching between them is straightforward.
Full documentation: docs/REST_API.md
import "github.com/Cepat-Kilat-Teknologi/go-routeros/rest"
client := rest.NewClient("192.168.88.1", "admin", "",
rest.WithInsecureSkipVerify(true),
)
ctx := context.Background()
// Auth
info, err := client.Auth(ctx)
// Print
result, err := client.Print(ctx, "ip/address",
rest.WithProplist("address", "interface"),
)
// Add
payload, _ := json.Marshal(map[string]string{
"address": "10.0.0.1/24", "interface": "ether1",
})
result, err := client.Add(ctx, "ip/address", payload)
// Remove
_, err := client.Remove(ctx, "ip/address/*1")Client Options: WithInsecureSkipVerify, WithTimeout, WithHTTPClient
Request Options: WithProplist, WithQuery, WithFilter
Error Type: *rest.APIError with StatusCode, Message, Detail
Full documentation: docs/API_PROTOCOL.md
import "github.com/Cepat-Kilat-Teknologi/go-routeros/api"
client, err := api.Dial("192.168.88.1", "admin", "")
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
// Auth
reply, err := client.Auth(ctx)
fmt.Println("Platform:", reply.Re[0].Map["platform"])
// Print with proplist and query
reply, err = client.Print(ctx, "/interface",
api.WithProplist("name", "type"),
api.WithQuery("?type=ether", "?type=vlan", "?#|"),
)
// Add
reply, err = client.Add(ctx, "/ip/address", map[string]string{
"address": "10.0.0.1/24", "interface": "ether1",
})
id, _ := reply.Done.Get("ret")
// Set
_, err = client.Set(ctx, "/ip/address", map[string]string{
".id": id, "comment": "Updated via API",
})
// Remove
_, err = client.Remove(ctx, "/ip/address", id)Client Options: WithTLS, WithTLSConfig, WithTimeout
Request Options: WithProplist, WithQuery
Error Types: *api.DeviceError (trap), *api.FatalError (fatal)
Authentication: Auto-detects post-6.43 (plaintext) and pre-6.43 (MD5 challenge-response)
For secure connections via API-SSL (port 8729) or REST HTTPS (port 443), certificates must be configured on the router.
Full guide: docs/TLS_SETUP.md
Quick summary:
# Generate CA and server certificate
/certificate add name=local-ca common-name=local-ca key-usage=key-cert-sign,crl-sign key-size=2048 days-valid=3650
/certificate sign local-ca ca-crl-host=192.168.88.1
/certificate add name=server common-name=server key-size=2048 days-valid=3650 subject-alt-name=IP:192.168.88.1
/certificate sign server ca=local-ca
# Assign to services and enable
/ip service set api-ssl certificate=server disabled=no
/ip service set www-ssl certificate=server disabled=no
// API Protocol with TLS
client, err := api.Dial("192.168.88.1", "admin", "password",
api.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
)
// REST API with HTTPS
client := rest.NewClient("https://192.168.88.1", "admin", "password",
rest.WithInsecureSkipVerify(true),
)go-routeros/
├── rest/ # REST API client (v7, HTTP/HTTPS)
│ ├── client.go # Client, NewClient, CRUD methods
│ ├── options.go # WithProplist, WithQuery, WithFilter
│ ├── errors.go # APIError
│ ├── request.go # HTTP request internals
│ ├── protocol.go # Protocol detection, TLS retry
│ └── constant.go # Constants
│
├── api/ # API Protocol client (v6 & v7, TCP)
│ ├── client.go # Client, Dial, Close, login, CRUD methods
│ ├── options.go # WithProplist, WithQuery
│ ├── errors.go # DeviceError, FatalError
│ ├── reply.go # Reply struct
│ ├── constant.go # Constants
│ └── proto/ # Wire protocol (binary encoding)
│ ├── sentence.go # Sentence, Pair, ParseWord
│ ├── reader.go # Length-prefix decoding
│ └── writer.go # Length-prefix encoding
│
├── example/
│ ├── rest/ # REST API examples (v7)
│ │ ├── basic/ # Auth, Print, Add, Remove
│ │ ├── proplist/ # Proplist filtering
│ │ ├── query/ # Complex query filtering (POST)
│ │ └── filter/ # URL parameter filtering (GET)
│ └── api/ # API Protocol examples (v6 & v7)
│ ├── basic/ # Dial, Auth, Print, Add, Remove
│ ├── proplist/ # Proplist filtering
│ ├── query/ # Stack-based query filtering
│ ├── set/ # Full CRUD cycle
│ ├── error-handling/ # DeviceError and FatalError handling
│ └── tls/ # TLS connection with certificate
│
├── docs/
│ ├── REST_API.md # Full REST API documentation
│ ├── API_PROTOCOL.md # Full API Protocol documentation
│ ├── TLS_SETUP.md # TLS/SSL certificate setup guide
│ └── MIGRATION.md # Migration from routerosv7-restfull-api
│
├── go.mod
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE # MIT
└── README.md
| Document | Description |
|---|---|
| docs/REST_API.md | Full REST API reference — client options, CRUD, queries, error handling |
| docs/API_PROTOCOL.md | Full API Protocol reference — dial options, queries, replies, auth |
| docs/TLS_SETUP.md | RouterOS certificate setup guide — CA, server cert, service config |
| docs/MIGRATION.md | Migration guide from routerosv7-restfull-api |
| CHANGELOG.md | Version history |
| CONTRIBUTING.md | Contribution guidelines and integration testing |
| SECURITY.md | Security policy and best practices |
See CONTRIBUTING.md for guidelines.
go test ./... -cover # Run tests (100% coverage required)
go vet ./... # Static analysisThis project is licensed under the MIT License - see the LICENSE file for details.