diff --git a/doc/stratum.md b/doc/stratum.md
new file mode 100644
index 000000000..450e97c7b
--- /dev/null
+++ b/doc/stratum.md
@@ -0,0 +1,556 @@
+# Grin Stratum RPC Protocol
+
+This document describes the current Stratum RPC protocol implemented in Grin.
+
+## Table of Contents
+
+1. [Messages](#messages)
+ 1. [getjobtemplate](#getjobtemplate)
+ 2. [job](#job)
+ 3. [keepalive](#keepalive)
+ 4. [login](#login)
+ 5. [status](#status)
+ 6. [submit](#submit)
+1. [Error Messages](#errormessages)
+1. [Miner Behavior](#minerbehavior)
+1. [Reference Implementation](#referenceimplementation)
+
+## Messages
+
+In this section, we detail each message and the potential response.
+
+At any point, if miner the tries to do one of the following request (except login) and login is required, the miner will receive the following error message.
+
+| Field | Content |
+| ------------- |:---------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | method sent by the miner |
+| error | {"code":-32500,"message":"login first"} |
+
+Example:
+
+```JSON
+{
+ "id":"10",
+ "jsonrpc":"2.0",
+ "method":"getjobtemplate",
+ "error":{
+ "code":-32500,
+ "message":"login first"
+ }
+}
+```
+
+if the request is not one of the following, the stratum server will give this error response:
+
+| Field | Content |
+| ------------- |:--------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | method sent by the miner |
+| error | {"code":-32601,"message":"Method not found"} |
+
+Example:
+
+```JSON
+{
+ "id":"10",
+ "jsonrpc":"2.0",
+ "method":"getgrins",
+ "error":{
+ "code":-32601,
+ "message":"Method not found"
+ }
+}
+```
+
+### ```getjobtemplate```
+
+A message initiated by the miner.
+Miner can request a job with this message.
+
+#### Request
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "getjobtemplate" |
+| params | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"2",
+ "jsonrpc":"2.0",
+ "method":"getjobtemplate",
+ "params":null
+}
+
+```
+
+#### Response
+
+The response can be of two types:
+
+##### OK response
+
+Example:
+
+``` JSON
+
+{
+ "id":"0",
+ "jsonrpc":"2.0",
+ "method":"getjobtemplate",
+ "result":{
+ "difficulty":1,
+ "height":13726,
+ "job_id":4,
+ "pre_pow":"00010000000000003c4d0171369781424b39c81eb39de10cdf4a7cc27bbc6769203c7c9bc02cc6a1dfc6000000005b50f8210000000000395f123c6856055aab2369fe325c3d709b129dee5c96f2db60cdbc0dc123a80cb0b89e883ae2614f8dbd169888a95c0513b1ac7e069de82e5d479cf838281f7838b4bf75ea7c9222a1ad7406a4cab29af4e018c402f70dc8e9ef3d085169391c78741c656ec0f11f62d41b463c82737970afaa431c5cabb9b759cdfa52d761ac451276084366d1ba9efff2db9ed07eec1bcd8da352b32227f452dfa987ad249f689d9780000000000000b9e00000000000009954"
+ }
+}
+
+ ```
+
+##### Error response
+
+If the node is syncing, it will send the following message:
+
+| Field | Content |
+| ------------- |:---------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "getjobtemplate" |
+| error | {"code":-32701,"message":"Node is syncing - Please wait"} |
+
+Example:
+
+```JSON
+{
+ "id":"10",
+ "jsonrpc":"2.0",
+ "method":"getjobtemplate",
+ "error":{
+ "code":-32000,
+ "message":"Node is syncing - Please wait"
+ }
+}
+```
+
+### ```job```
+
+A message initiated by the Stratum server.
+Stratum server will send job automatically to connected miners.
+
+#### Request
+
+| Field | Content |
+| ------------- |:-------------------------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "job" |
+| params | Int ```difficulty```, ```height```, ```job_id``` and string ```pre_pow``` |
+
+Example:
+
+``` JSON
+
+{
+ "id":"Stratum",
+ "jsonrpc":"2.0",
+ "method":"job",
+ "params":{
+ "difficulty":1,
+ "height":16375,
+ "job_id":5,
+ "pre_pow":"00010000000000003ff723bc8c987b0c594794a0487e52260c5343288749c7e288de95a80afa558c5fb8000000005b51f15f00000000003cadef6a45edf92d2520bf45cbd4f36b5ef283c53d8266bbe9aa1b8daaa1458ce5578fcb0978b3995dd00e3bfc5a9277190bb9407a30d66aec26ff55a2b50214b22cdc1f3894f27374f568b2fe94d857b6b3808124888dd5eff7e8de7e451ac805a4ebd6551fa7a529a1b9f35f761719ed41bfef6ab081defc45a64a374dfd8321feac083741f29207b044071d93904986fa322df610e210c543c2f95522c9bdaef5f598000000000000c184000000000000a0cf"
+ }
+}
+
+```
+
+#### Response
+
+No response is required for this message.
+
+### ```keepalive```
+
+A message initiated by the miner in order to keep the connection alive.
+
+#### Request
+
+| Field | Content |
+| ------------- |:----------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "keepalive" |
+| params | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"2",
+ "jsonrpc":"2.0",
+ "method":"keepalive",
+ "params":null
+}
+
+```
+
+#### Response
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "keepalive" |
+| result | "ok" |
+| error | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"2",
+ "jsonrpc":"2.0",
+ "method":"keepalive",
+ "result":"ok",
+ "error":null
+}
+
+```
+
+### ```login```
+
+***
+
+A message initiated by the miner.
+Miner can log in on a Grin Stratum server with a login, password and agent (usually statically set by the miner program).
+
+#### Request
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "login" |
+| params | Strings: login, pass and agent |
+
+Example:
+
+``` JSON
+
+{
+ "id":"0",
+ "jsonrpc":"2.0",
+ "method":"login",
+ "params":{
+ "login":"login",
+ "pass":"password",
+ "agent":"grin-miner"
+ }
+}
+
+```
+
+#### Response
+
+The response can be of two types:
+
+##### OK response
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "login" |
+| result | "ok" |
+| error | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"1",
+ "jsonrpc":"2.0",
+ "method":"login",
+ "result":"ok",
+ "error":null
+}
+
+```
+
+##### Error response
+
+Not yet implemented. Should return error -32500 "Login first".
+
+### ```status```
+
+A message initiated by the miner.
+This message allows a miner to get the status of its current worker and the network.
+
+#### Request
+
+| Field | Content |
+| ------------- |:----------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "status" |
+| params | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"2",
+ "jsonrpc":"2.0",
+ "method":"status",
+ "params":null
+}
+
+```
+
+#### Response
+
+The response is the following:
+
+| Field | Content |
+| ------------- |:--------------------------------------------------------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "status" |
+| result | String ```id```. Integers ```height```, ```difficulty```, ```accepted```, ```rejected``` and ```stale``` |
+| error | null |
+
+Example:
+
+```JSON
+{
+ "id":"5",
+ "jsonrpc":"2.0",
+ "method":"status",
+ "result":{
+ "id":"5",
+ "height":13726,
+ "difficulty":1,
+ "accepted":0,
+ "rejected":0,
+ "stale":0
+ },
+ "error":null
+}
+```
+
+### ```submit```
+
+A message initiated by the miner.
+When a miner find a share, it will submit it to the node.
+
+#### Request
+
+The miner submit a solution to a job to the Stratum server.
+
+| Field | Content |
+| ------------- |:---------------------------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| params | Int ```nonce```, ```height```, ```job_id``` and array of integers ```pow``` |
+
+Example:
+
+``` JSON
+
+{
+ "id":"0",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "params":{
+ "height":16419,
+ "job_id":0,
+ "nonce":8895699060858340771,
+ "pow":[
+ 4210040,10141596,13269632,24291934,28079062,84254573,84493890,100560174,100657333,120128285,130518226,140371663,142109188,159800646,163323737,171019100,176840047,191220010,192245584,198941444,209276164,216952635,217795152,225662613,230166736,231315079,248639876,263910393,293995691,298361937,326412694,330363619,414572127,424798984,426489226,466671748,466924466,490048497,495035248,496623057,502828197, 532838434
+ ]
+ }
+}
+
+```
+
+#### Response
+
+The response can be of three types.
+
+##### OK response
+
+The share is accepted by the Stratum but is not a valid cuckoo solution at the network target difficulty.
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| result | "ok" |
+| error | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"2",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "result":"ok",
+ "error":null
+}
+
+```
+
+##### Blockfound response
+
+The share is accepted by the Stratum and is a valid cuckoo solution at the network target difficulty.
+
+| Field | Content |
+| ------------- |:------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| result | "block - " + hash of the block |
+| error | null |
+
+Example:
+
+``` JSON
+
+{
+ "id":"6",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "result":"blockfound - 23025af9032de812d15228121d5e4b0e977d30ad8036ab07131104787b9dcf10",
+ "error":null
+}
+
+```
+
+##### Error response
+
+The error response can be of two types: stale and rejected.
+
+##### Stale share error response
+
+The share is a valid solution to a previous job not the current one.
+
+| Field | Content |
+| ------------- |:---------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| error | {"code":-32503,"message":"Solution submitted too late"} |
+
+Example:
+
+```JSON
+{
+ "id":"5",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "error":{
+ "code":-32503,
+ "message":"Solution submitted too late"
+ }
+}
+```
+
+##### Rejected share error responses
+
+Two possibilities: the solution cannot be validated or the solution is of too low difficulty.
+
+###### Failed to validate solution error
+
+The submitted solution cannot be validated.
+
+| Field | Content |
+| ------------- |:---------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| error | {"code":-32502,"message":"Failed to validate solution"} |
+
+Example:
+
+```JSON
+{
+ "id":"5",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "error":{
+ "code":-32502,
+ "message":"Failed to validate solution"
+ }
+}
+```
+
+###### Share rejected due to low difficulty error
+
+The submitted solution is of too low difficulty.
+
+| Field | Content |
+| ------------- |:----------------------------------------------------------------:|
+| id | ID of the request |
+| jsonrpc | "2.0" |
+| method | "submit" |
+| error | {"code":-32501,"message":"Share rejected due to low difficulty"} |
+
+Example:
+
+```JSON
+{
+ "id":"5",
+ "jsonrpc":"2.0",
+ "method":"submit",
+ "error":{
+ "code":-32501,
+ "message":"Share rejected due to low difficulty"
+ }
+}
+```
+
+## Error Messages
+
+Grin Stratum protocol implementation contains the following error message:
+
+| Error code | Error Message |
+| ----------- |:--------------------------------------:|
+| -32000 | Node is syncing - please wait |
+| -32500 | Login first |
+| -32501 | Share rejected due to low difficulty |
+| -32502 | Failed to validate solution |
+| -32503 | Solution Submitted too late |
+| -32600 | Invalid Request |
+| -32601 | Method not found |
+
+## Miner behavior
+
+Miners SHOULD, MAY or MUST respect the following rules:
+
+- Miners SHOULD randomize the job nonce before starting (not the way it is now, the way it should be)
+- Miners MUST continue mining the same job until the server sends a new one, though a miner MAY request a new job at any time
+- Miners MUST NOT send an rpc response to a job request from the server
+- Miners MAY set the RPC "id" and expect responses to have that same id
+- Miners MAY send a keepalive message
+- Miners MAY send a login request (to identify which miner finds shares / solutions in the logs), the login request MUST have all 3 params.
+- Miners MUST return the supplied job_id with submit messages.
+
+## Reference Implementation
+
+The current reference implementation is available at [mimblewimble/grin-miner](https://github.com/mimblewimble/grin-miner/blob/master/src/bin/client.rs).
\ No newline at end of file
diff --git a/doc/table_of_contents.md b/doc/table_of_contents.md
index 0d61209db..510e7a190 100644
--- a/doc/table_of_contents.md
+++ b/doc/table_of_contents.md
@@ -15,6 +15,7 @@
- [merkle_proof graph](merkle_proof/merkle_proof.png) - Example merkle proof with pruning applied
- [pruning](pruning.md) - Technical explanation of pruning
- [rangeproofs](rangeproofs.md) - Technical explanation of range proofs
+- [stratum](stratum.md) - Technical explanation of Grin Stratum RPC protocol
- [transaction UML](transaction/aggregating transaction without lock_height) - UML of an interactive transaction
## Build and use