Since March 10, 2003 - Version 2

MSN Messenger Protocol

Home Page






Validate XHTML
Validate CSS
General - Commands
Printable Version

What are commands?

Everything sent between the client and the server is in the form of a command. Every command is represented with a three letter, all-caps, command code. All normal commands have a transaction ID (explained below) and end with a newline (also explained below).


There are three special types of commands which behave slightly differently than normal commands. Some commands, explained in the Payload Commands page, span over multiple lines and therefore must be dealt with differently. Sometimes, when the client sends something invalid, the server will respond with an error command. Error command codes are always three digit numbers, as opposed to normal three letter codes. Also, certain commands sent by the server only, such as NLN, FLN, and BPR will not contain transaction IDs.

Transaction IDs (TrIDs)

Transaction IDs, abbreviated as TrIDs, are used to match a client command with a server response. Every command sent by the client is required to contain a TrID, and every command from the server sent in direct response to that command will contain the same TrID (PNG and QNG are the only exceptions). In most cases, there will be just one response to each client command.

Every TrID is a number between 0 and 4294967295 (2^32 - 1). Even though completely legal, it is advisable not to use 0 as a TrID because some asynchronous commands use 0 as the TrID and may cause confusion. The TrID always comes right after the three letter (or three digit, in the case of errors) command code, and they are separated by a space. If the command has parameters, the parameters will follow the TrID and they will be separated by another space. Otherwise, there will be no space after the TrID. Below is an example of sending the INF command with a TrID of 15 and receiving the response from the server.

>>> VER 15 MSNP7 FOO BAR\r\n

<<< VER 15 MSNP7\r\n

The server does not make any changes based on your TrID; it only responds using the same TrID you sent it. If your TrID is greater than 4294967295, the server will have unpredictable results. If you send a TrID that is not a positive integer, the server will immediately disconnect you. If you repeat the same TrID in multiple commands, the server will not do anything differently, but it will be more difficult for the client to track responses.

The official client always increments the TrID by one after sending each command. As long as you stay in the correct range and don't repeat TrIDs, it doesn't make much of a difference. Keeping the number low will save a small amount of bandwidth (maybe as much as 10 kilobytes during the synchronization process). Using random numbers will increase your processor use and not increase your security at all.


Parameters exist to provide additional information with each command. Parameters come after the TrID in a command, and before the newline. Some commands do not have parameters, and have the newline right after the TrID. Each parameter is separated by a space. For the purposes of this documentation, the TrID does not count as a parameter. The following command has three parameters:

<<< ILN 9 NLN My%20Name\r\n

The first parameter is NLN, the second parameter is, and the third parameter is My%20Name.

It is possible to send certain commands with multiple spaces between parameters, tabs instead of spaces, tabs mixed with spaces, and trailing spaces and tabs. This has not been thoroughly tested. In any case, the server always sends one space in between parameters and no trailing whitespace (with the exception of the standard newlines).


Every normal command ends with a newline (see the Payload Commands page for exceptions). The use of \r and \n throughout this document are explained here. The official client always ends commands with \r\n and the server always ends commands with \r\n. It is recommended that you do this too.

However, the server will accept commands ending with just \n, but not just \r. If you are looking to save as much bandwidth as possible, go ahead and use \n, and there shouldn't be any problems unless MSN changes their server code.

Inside the payloads of payload commands, newlines are treated slightly differently. Their behavior is discussed in the Payload Commands page.


An error is a special type of command sent by the server in response to a client command. Errors follow all of the normal rules of commands, except that the three-character command codes are always three-digit numbers. A detailed list of errors can be found in the Error List page.

If something goes wrong, an error will be sent in place of the expected command. For example, if a client sends an ADD command, it should normally receive another ADD command back from the server. However, if the client specifies a nonexistent account name as a parameter, the server will respond with error 201 instead of the ADD command.

Clients never send error codes to the server. The server never sends error codes that aren't in response to any particular client command.

Error Syntax

The syntax of an error command is very simple. The command code is just a three digit number, and it specifies the TrID of the client command it is in response to. There are no additional parameters.

However, according to the original IETF draft, errors can be sent with additional parameters. I have never seen anything like that sent, but just in case, every client should be prepared to receive parameters without crashing.

Command Order

Usually, replies to commands will come in the order that you sent the commands. But this is not always the case. Sometimes, you may send commands in the order of 1, 2, 3, and the server will respond to them in the order of 2, 3, 1. This is why TrIDs are very useful.

Some commands have multiple responses from the server. All of these responses contain the original TrID of the original command (or none at all if they are asynchronous commands). Two commands that often have multiple responses are CHG and SYN.

Unfortunately, there are no real rules on the order of unrelated commands. For example, a client can receive an ILN in the middle of a list of BPRs. If you examine the server behavior enough, you can start to make rules, but Microsoft often changes the server implementation and you would have to start all over. It's best for a client to just expect anything to happen.

List Commands

Certain commands from the server are sent in the form of a list with multiple items. Examples of this commands are LST, LSG, IRO, and FND. The exact syntax of each command is discussed in its respective page.

In the list format, each item is sent as a separate command. Each command will have two special numbers: an incrementing number and a total number. The incrementing number starts at one for the first item and is incremented by one for each item. The total number is the number of items in the list. When the incrementing number is equal to the total number, the client knows that the list is complete. If there are no items in the list, both numbers will be zero.

Asynchronous Commands

Asynchronous commands are commands sent by the server, but not in response to any command sent by the client. Because of their nature, they have no assigned TrID. Some asynchronous commands have no TrID, and just have the parameter immediately after the command code. Some of these commands are NLN, FLN, and BPR.

Other asynchronous commands always have a TrID of zero. Some of these commands are ADD, REM, and CHL. The reason that some (but not all) of these commands still have TrIDs is because they are also used as a client command with a server response. Only in special cases, like where a user is added to the reverse list, does the server send the command as an asynchronous command with a TrID of zero.

Asynchronous commands can be sent at any legal place in the protocol - even between a block of related replies such as in between two ILNs.

Client Pings (PNG/QNG)

Client pings (PNG and QNG), described in the Pings page are the only commands without TrIDs that are not asynchronous. They are very simple because they have no parameters at all. As always, these pings can interrupt command blocks.

Copyright ©2002-2003 to Mike Mintz.