diff --git a/rpc.md b/rpc.md
index 6d70b7fd4232f0417c615dbdd6e03a1fcca5ebc8..e45193bb7766cf84881b8647231a7fda8f655d2b 100644
--- a/rpc.md
+++ b/rpc.md
@@ -75,7 +75,7 @@ Noise_NK_25519_ChaChaPoly_BLAKE2s
 
 This noise protocol uses ECDH asymmetric encryption with
 XChaCha20Poly1305 symmetric encryption and Blake2s hashes inside of the
-protocol.  Additionally, the prologue is set to the current DM protocol
+protocol.  Additionally, the prologue is set to the current RPC protocol
 version (`0x0 0x0` at the time of this writing). Full details on Noise
 Protocol and the syntax used above can be found in the
 [noise specification document](https://noiseprotocol.org/noise.html).
@@ -88,25 +88,108 @@ many RPC APIs.
 
 ## Reception IDs
 
-The `server` can select it's own reception ID. This can be derived from the
+The `server` can select it's own reception ID. This can be derived
+from its public key, manually set by the operator, or through some
+other method. A pseudorandomly generated ID shall be the
+default. Reception of each message will be determined by encrypting
+for the server's static key, so using the same reception ID is not a
+concern.
 
-...
-
-The `client` selects a random id determined by the key they generate. This is one-time use..
+The `client` selects a random id determined by the key they
+generate. This is a one-time use key and reception ID. For simplicity,
+the client shall be live the entire time this temporary reception ID
+is in use, so no storage will be necessary to e.g., receive a response
+after the client is closed.
 
 
 ## RPC Messages
 
 Every RPC message has the following contents of note:
 
-....
+```
+message RPCMessage{
+    byte Version = 1;
+    ...
+    bytes PubKey = 3;
+    ...
+    bytes Ciphertext = 5;
+    ...
+    bytes Nonce = 7;
+}
 
+```
+
+These fields are used as follows:
+* `Version` of the rpc message, set to 0x0.
+* `PubKey` the public key sent as part of the NK Noise protocol.
+* `Ciphertext` of the request or response.
+* `Nonce` set by the sender to avoid repeats. Repeated
+  nonces should be ignored.
+
+Requests and responses look the same from a cMix packet perspective.
 
 ## RPC Encryption
 
+The format of the plaintext inside the RPC ciphertext for the request or the
+response uses a message partitioning format:
+
+```
+plaintext = varuint(len(message)) | varuint(offset) | message
+```
+
+Where:
+* `varuint` is a variable length integer encoding of an unsigned integer.
+* `len` is the length function.
+* `offset` number of bytes into the message that this part represents.
+* `message` the contents of the request or response.
+
 ### Request
 
+The sender client creates and encrypts the request plaintext as follows:
+
+```
+requestPublicKey, requestPrivateKey = generateKeyPair(rng)
+key = H(DH(requestPrivateKey, RPCServerStaticPublicKey))
+ciphertext = NoiseNK.Encrypt(key, plaintext)
+```
+
 ### Response
 
+The server creates and encrypts the plaintext response as follows:
+
+```
+responsePublicKey, responsePrivateKey = generateKeyPair(rng)
+key = H(DH(responsePrivateKey, requestPublicKey))
+ciphertext = NoiseNK.Encrypt(key, plaintext)
+```
 
 ## Security Considerations
+
+The cMix protocol is providing the metadata protection and Noise is
+providing all of the core confidentiality properties. A nonce and timestamp
+prevent excessive resending of the same request and replays.
+
+Requests are encryption to a known recipient, which provides forward
+secrecy for sender compromise only. Without the nonce this message can
+be replayed, since there's no ephemeral contribution from the
+recipient.
+
+For requests, the payload is also encrypted based only on DHs
+involving the recipient's static key pair. If the server's static
+private key is compromised, even at a later date, this payload can be
+decrypted. You can mitigate by rotating the key, creating keys for
+specific users, or another method.
+
+Responses are encryption to an ephemeral recipient, so the payload has
+forward secrecy as the encryption involves an ephemeral-ephemeral DH
+(`ee`). However, the sender cannot authenticate the recipient, which
+means the RPC server must treat all requests as untrusted. This could
+be used to exhaust resources, but can be mitigated with anonymized api
+keys, paid return postage, or another mechanism.
+
+The identity of the requestor remains protected in all cases because
+it is not transmitted. It is important that the RPC protocol itself
+not add information which could be used to break this protection. The
+server also enjoys significant protection but is using a "public"
+address in practice, so while it's physical location is protected its
+cMix address is protected via recipient ID collisions.