diff --git a/protocol.md b/protocol.md
new file mode 100644
--- /dev/null
+++ b/protocol.md
@@ -0,0 +1,96 @@
+# Protocol #
+
+[Communication protocol proposal. Not yet fully implemented and expected to change.]
+
+Nodes communicate by exchanging messages through network sockets. Basic message format is simple:
+
+ json-length: ABC
+ bin-length: DEF
+ {... JSON payload ...}
+ ... binary payload ...
+
+`ABC` is the JSON payload length (decimal integer), `DEF` is the binary payload length. JSON payload always contains a "command" field.
+
+The client sends a request (a message) and the server answers with a response (another message).
+
+
+## Commands ##
+### init ###
+Initiates communication between the client and the server. Checks that the nodes can meaningfully talk to each other.
+
+#### Params ####
+- (str) version: program version. Both the client and the server are to check for compatibility with their partner.
+- {push, pull} action: what the client desires to do
+- (str) filename: name of the file to be synchronized
+- (int) blockSize
+- (int) blockCount
+
+#### Responses ####
+- [init](#r-init)
+- [deny](#deny)
+
+
+### req ###
+Requests hashes or a data chunk from the server.
+
+#### Params ####
+- {hash, data} dataType
+
+hash
+- [(int) i0, ...] index: list of requested node keys from the HashTree
+
+data
+- (int) index: requested data block number in the data file. Returns blockSize bytes starting at blockSize * index.
+
+#### Responses ####
+- [send](#send)
+- [err](#err)
+
+
+### send ####
+Sends data. Can be a client action or a response to a request.
+
+#### Params ####
+- {hash, data} dataType
+- index: see [req](#req)
+
+#### Responses ####
+- [ack](#ack)
+- [err](#err)
+
+
+### end ###
+Cease talking and close the connection.
+
+#### Params ####
+- {push} (optional) action: unlocks the server's dirty lock
+
+#### Responses ####
+- end
+
+
+## Responses ##
+### init ###
+See [the init command](#init). If the client doesn't like server's protocol version, it is free to [end](#end) the connection.
+
+#### Params ####
+- (str) version
+
+
+### deny ###
+The server refuses connection. It might be busy, corrupted or incompatible.
+
+#### Params ####
+- (int) retry: suggested delay in seconds before another attempt at connection
+- (str) msg
+
+
+### ack ###
+Everything is alright, but the server has nothing better to say.
+
+
+### err ###
+Something bad happened.
+
+#### Params ####
+- (str) msg