A payload command is a special type of command that spans multiple lines. The best way to think of these commands is as regular single-line commands followed by a chunk of binary data (the "payload"). The last parameter of the command always specifies the number of bytes in the payload.
Unlike commands, payloads themselves have no universal format. Their format is defined by the rules of each specific payload command. You cannot separate them from the regular command flow by trying to figure out where they end - for example, payloads don't have to end with a newline. You must read the number of bytes specified in the command and read exactly that number of bytes for the payload.
Some payload commands have TrIDs, some don't. The command can have any number of parameters, but the last parameter is always a positive integer. This number represents the length of the payload in bytes. Certain commands have specific limits on the length of the payload. After the payload length, comes a newline just like any other command. Right after the newline comes the payload itself. It will always be the specified length in bytes. After the payload, normal command flow resumes.
Sending payload commands is very easy. Most programming languages have a function that will find the length of the string you are sending in bytes (probably called "len()" or something like that) - use this to find the length of your payload. Remember not to include the command itself or the newline at the end of the command when calculating the payload length.
Note that the server relies on the message length that you provide. If you say that you are going to send 88 bytes and you send 87, the server will wait until you send something else, and then interpret the first byte of the next command as the last byte of the payload. You will end up sending an invalid command to the server. Similar problems will occur if your message length is too short.
Receiving payload commands is much harder. You cannot rely on the entire command to be in one packet, or to end with a newline. You absolutely must read the specified message length, and read that many bytes out of the socket after the initial newline. For suggestions on how to implement this, read this frequently asked question.
Messages were the first and are arguably the most important payload command in the protocol. They are represented by the MSG
command. Because messages are very common and are used in both the NS and the SB, the syntax will be described here.
When receiving MSG
s, the command will always have no TrID and two parameters before the payload length parameter. The first parameter is the account name of the source of the message and the second parameter is the URL-encoded display name for the source. On the NS, the account name and display name are always both Hotmail
(even though that is not a valid email address), but that might be subject to change. On the SB, the two parameters are the account name and display name of the source of the message.
When sending messages, you must include a TrID and one parameter specifying the acknowledgment you wish to receive from the server. You can only send message in an SB session, not in an NS session. More details about the syntax of outgoing messages are described in the Switchboard Messages page.
When sending messages, because the server does not interpret the payload, you can send anything you want in the payload, as long as it's not too long and the payload length parameter is correct. However, the payloads of messages are expected to be formatted in a particular way.
Much like in MIME, each message is divided into a header and a body. The header and body are separated by the first appearance of new newlines in a row.
The header of a message should be in the form of a standard MIME header as described in RFC 1521. The MIME header consists of an unordered list of fields separated by newlines. Each newline must be a \r\n
, or else it will not be interpreted properly by the official client.
Every field has a key and a value, for example:
preferredEmail: example@passport.com
The key should be considered case-sensitive. Third party clients should always send field key names in the case provided in this documentation. The last character of a key must be a colon, and will be followed by a space. The key can't have a colon anywhere else in it, but the value can have several or none. For example, in file transfer, one client might send:
Request-Data: IP-Address:
And the other client might come back with:
IP-Address: 10.44.102.65
Additional parameters may be specified in any one field. Each parameter is separated by a semi-colon followed by a space, and each parameter should be a key/value pair separated by an equal sign. Below is an example of a field with five parameters:
X-MMS-IM-Format: FN=Arial; EF=I; CO=ff0000; CS=0; PF=22
Because fields are unordered, a client must be prepared to see them in any order, regardless of the fact that the official client always sends fields in the same order. Also, a client must be prepared to receive messages with unknown fields and should ignore these. For example, Gaim will include a field something like User-Agent: Gaim/0.59
in all of its messages.
Every valid message is required to have a Content-Type
field identifying what type of message it is. Every message should also have a MIME-Version
field, but the official client still displays messages without that field.
The body of the message can pretty much be anything. If the header of the message specifies that the body of the message is UTF-8 encoded, then the body should be UTF-8 encoded. Note that this does not affect the message length. You must calculate the message length based on the raw number of bytes, and not the number of "characters".
In regular text messages, the official client adds newlines with \r\n
. These are to be interpreted as actual line breaks in the message. Note that the official client only parses \r
, so you can end lines with \r
and it would work the same as ending lines with \r\n
. Ending lines with just \n
will not work. For this reason, you must be prepared to receive messages with lines ending in \r
. All \n
's are completely ignored by the official client.
It's possible for messages to have no body. If you just end a message with the two newlines at the end of the header, it will have an empty body.