...
Length of the word is encoded as follows:
Value of length | # of bytes | Encoding |
---|---|---|
0 <= len <= 0x7F | 1 | len, lowest byte |
0x80 <= len <= 0x3FFF | 2 | len | 0x8000, two lower bytes |
0x4000 <= len <= 0x1FFFFF | 3 | len | 0xC00000, three lower bytes |
0x200000 <= len <= 0xFFFFFFF | 4 | len | 0xE0000000 |
len >= 0x10000000 | 5 | 0xF0 and len as four bytes |
- Each word is encoded as length, followed by that many bytes of content;
- Words are grouped into sentences. End of a sentence is terminated by zero-length word;
- The scheme allows encoding of length up to 0x7FFFFFFFFF, only four-byte length is supported;
- len bytes are sent most significant first (network order);
- If the first byte of the word is >= 0xF8, then it is a reserved control byte. After receiving unknown control byte API client cannot proceed, because it cannot know how to interpret the following bytes;
- Currently, control bytes are not used;
...
Note: that each command and response ends with an empty word.
Login method post-v6.43:
/login |
=name=admin |
=password= |
!done |
- Now the client sends a username and password in the first message.
- Password is sent in plain text.
- in case of error, the reply contains =message=error message.
- In case of a successful login, the client can start to issue commands.
...
- Query words begin with '?'.
- The order of query words is significant. A query is evaluated starting from the first word.
- A query is evaluated for each item in the list. If the query succeeds, the item is processed, if a query fails, the item is ignored.
- A query is evaluated using a stack of boolean values. Initially, the stack contains an infinite amount of 'true' values. At the end of the evaluation, if the stack contains at least one 'false' value, the query fails.
- Query words operate according to the following rules:
Query | Description |
---|---|
?name | pushes 'true' if an item has a value of property name, 'false' if it does not. |
?-name | pushes 'true' if an item does not have a value of property name, 'false' otherwise. |
?name=x ?=name=x | pushes 'true' if the property name has a value equal to x, 'false' otherwise. |
?<name=x | pushes 'true' if the property name has a value less than x, 'false' otherwise. |
?>name=x | pushes 'true' if the property name has a value greater than x, 'false' otherwise. |
?#operations | applies operations to the values in the stack.
|
Warning |
---|
Regular expressions are not supported in API, so do not try to send a query with the ~ symbol |
...
In console, OID values can be seen by running 'print oid' command. In API, these properties have name that ends with ".oid", and can be retrieved by adding their name to the value of '.proplist'. An example:
/system/resource/print |
=.proplist=uptime,cpu-load,uptime.oid,cpu-load.oid |
!re |
=uptime=01:22:53 |
=cpu-load=0 |
=uptime.oid=.1.3.6.1.2.1.1.3.0 |
=cpu-load.oid=.1.3.6.1.2.1.25.3.3.1.2.1 |
!done |
!trap
When for some reason API sentence fails trap is sent in return accompanied with message attribute and on some occasions category argument.
...
Command examples
/system/package/getall
/system/package/getall |
!re |
=.id=*5802 |
=disabled=no |
=name=routeros-x86 |
=version=3.0beta2 |
=build-time=oct/18/2006 16:24:41 |
=scheduled= |
!re |
=.id=*5805 |
=disabled=no |
=name=system |
=version=3.0beta2 |
=build-time=oct/18/2006 17:20:46 |
=scheduled= |
... more !re sentences ... |
!re |
=.id=*5902 |
=disabled=no |
=name=advanced-tools |
=version=3.0beta2 |
=build-time=oct/18/2006 17:20:49 |
=scheduled= |
!done |
/user/active/listen
/user/active/listen |
!re |
=.id=*68 |
=radius=no |
=when=oct/24/2006 08:40:42 |
=name=admin |
=address=0.0.0.0 |
=via=console |
!re |
=.id=*68 |
=.dead=yes |
... more !re sentences ... |
/cancel, simultaneous commands
/login |
!done |
=ret=856780b7411eefd3abadee2058c149a3 |
/login |
=name=admin |
=response=005062f7a5ef124d34675bf3e81f56c556 |
!done |
-- first start listening for interface changes (tag is 2) |
/interface/listen |
.tag=2 |
-- disable interface (tag is 3) |
/interface/set |
=disabled=yes |
=.id=ether1 |
.tag=3 |
-- this is done for disable command (tag 3) |
!done |
.tag=3 |
-- enable interface (tag is 4) |
/interface/set |
=disabled=no |
=.id=ether1 |
.tag=4 |
-- this update is generated by change made by first set command (tag 3) |
!re |
=.id=*1 |
=disabled=yes |
=dynamic=no |
=running=no |
=name=ether1 |
=mtu=1500 |
=type=ether |
.tag=2 |
-- this is done for enable command (tag 4) |
!done |
.tag=4 |
-- get interface list (tag is 5) |
/interface/getall |
.tag=5 |
-- this update is generated by change made by second set command (tag 4) |
!re |
=.id=*1 |
=disabled=no |
=dynamic=no |
=running=yes |
=name=ether1 |
=mtu=1500 |
=type=ether |
.tag=2 |
-- these are replies to getall command (tag 5) |
!re |
=.id=*1 |
=disabled=no |
=dynamic=no |
=running=yes |
=name=ether1 |
=mtu=1500 |
=type=ether |
.tag=5 |
!re |
=.id=*2 |
=disabled=no |
=dynamic=no |
=running=yes |
=name=ether2 |
=mtu=1500 |
=type=ether |
.tag=5 |
-- here interface getall ends (tag 5) |
!done |
.tag=5 |
-- stop listening - request to cancel command with tag 2, cancel itself uses tag 7 |
/cancel |
=tag=2 |
.tag=7 |
-- listen command is interrupted (tag 2) |
!trap |
=category=2 |
=message=interrupted |
.tag=2 |
-- cancel command is finished (tag 7) |
!done |
.tag=7 |
-- listen command is finished (tag 2) |
!done |
.tag=2 |
Example client
A simple API client in Python3
...
API implementations in different languages, provided by different sources. They are not ordered in any particular order.
in the Wiki
...