diff --git a/api/authenticatedChannel.go b/api/authenticatedChannel.go
new file mode 100644
index 0000000000000000000000000000000000000000..7c53e2389b5fd1526c02a928e1c8acd9e28b4df5
--- /dev/null
+++ b/api/authenticatedChannel.go
@@ -0,0 +1,28 @@
+package api
+
+import jww "github.com/spf13/jwalterweatherman"
+
+// CreateAuthenticatedChannel creates a 1-way authenticated channel
+// so this user can send messages to the desired recipient Contact.
+// To receive confirmation from the remote user, clients must
+// register a listener to do that.
+func (c *Client) CreateAuthenticatedChannel(recipient Contact,
+	payload []byte) error {
+	jww.INFO.Printf("CreateAuthenticatedChannel(%v, %v)",
+		recipient, payload)
+	return nil
+}
+
+// RegisterAuthConfirmationCb registers a callback for channel
+// authentication confirmation events.
+func (c *Client) RegisterAuthConfirmationCb(cb func(contact Contact,
+	payload []byte)) {
+	jww.INFO.Printf("RegisterAuthConfirmationCb(...)")
+}
+
+// RegisterAuthRequestCb registers a callback for channel
+// authentication request events.
+func (c *Client) RegisterAuthRequestCb(cb func(contact Contact,
+	payload []byte)) {
+	jww.INFO.Printf("RegisterAuthRequestCb(...)")
+}
diff --git a/api/client.go b/api/client.go
index 1e73696714b09edc674874d6db43324e8d19b374..4244899234c5a1ab4157ae7f4741382086f99365 100644
--- a/api/client.go
+++ b/api/client.go
@@ -18,13 +18,11 @@ import (
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/switchboard"
 	"gitlab.com/elixxir/comms/client"
-	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/large"
 	"gitlab.com/xx_network/crypto/signature/rsa"
-	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/ndf"
 	"time"
 )
@@ -218,7 +216,13 @@ func loadClient(session *storage.Session, rngStreamGen *fastRNG.StreamGenerator)
 //	 - Garbled Messages (/network/message/garbled.go)
 //		Can be signaled to check all recent messages which could be be decoded
 //		Uses a message store on disk for persistence
-
+//	 - Critical Messages (/network/message/critical.go)
+//		Ensures all protocol layer mandatory messages are sent
+//		Uses a message store on disk for persistence
+//	 - KeyExchange Trigger (/keyExchange/trigger.go)
+//		Responds to sent rekeys and executes them
+//   - KeyExchange Confirm (/keyExchange/confirm.go)
+//		Responds to confirmations of successful rekey operations
 func (c *Client) StartNetworkFollower() error {
 	jww.INFO.Printf("StartNetworkFollower()")
 
@@ -271,217 +275,20 @@ func (c *Client) NetworkFollowerStatus() Status {
 	return c.status.get()
 }
 
-
-
-
-// SendE2E sends an end-to-end payload to the provided recipient with
-// the provided msgType. Returns the list of rounds in which parts of
-// the message were sent or an error if it fails.
-func (c *Client) SendE2E(payload []byte, recipient id.ID, msgType int) (
-	[]int, error) {
-	jww.INFO.Printf("SendE2E(%s, %s, %d)", payload, recipient,
-		msgType)
-	return nil, nil
-}
-
-// SendUnsafe sends an unencrypted payload to the provided recipient
-// with the provided msgType. Returns the list of rounds in which parts
-// of the message were sent or an error if it fails.
-// NOTE: Do not use this function unless you know what you are doing.
-// This function always produces an error message in client logging.
-func (c *Client) SendUnsafe(payload []byte, recipient id.ID, msgType int) ([]int,
-	error) {
-	jww.INFO.Printf("SendUnsafe(%s, %s, %d)", payload, recipient,
-		msgType)
-	return nil, nil
-}
-
-// SendCMIX sends a "raw" CMIX message payload to the provided
-// recipient. Note that both SendE2E and SendUnsafe call SendCMIX.
-// Returns the round ID of the round the payload was sent or an error
-// if it fails.
-func (c *Client) SendCMIX(payload []byte, recipient id.ID) (int, error) {
-	jww.INFO.Printf("SendCMIX(%s, %s)", payload, recipient)
-	return 0, nil
-}
-
-// RegisterListener registers a listener callback function that is called
-// every time a new message matches the specified parameters.
-func (c *Client) RegisterListenerCb(uid id.ID, msgType int, username string,
-	listenerCb func(msg Message)) {
-	jww.INFO.Printf("RegisterListener(%s, %d, %s, func())", uid, msgType,
-		username)
-}
-
-// RegisterForNotifications allows a client to register for push
-// notifications.
-// Note that clients are not required to register for push notifications
-// especially as these rely on third parties (i.e., Firebase *cough*
-// *cough* google's palantir *cough*) that may represent a security
-// risk to the user.
-func (c *Client) RegisterForNotifications(token []byte) error {
-	jww.INFO.Printf("RegisterForNotifications(%s)", token)
-	// // Pull the host from the manage
-	// notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
-	// if !ok {
-	// 	return errors.New("Failed to retrieve host for notification bot")
-	// }
-
-	// // Send the register message
-	// _, err := cl.receptionManager.Comms.RegisterForNotifications(notificationBotHost,
-	// 	&mixmessages.NotificationToken{
-	// 		Token: notificationToken,
-	// 	})
-	// if err != nil {
-	// 	err := errors.Errorf(
-	// 		"RegisterForNotifications: Unable to register for notifications! %s", err)
-	// 	return err
-	// }
-
-	return nil
-}
-
-// UnregisterForNotifications turns of notifications for this client
-func (c *Client) UnregisterForNotifications() error {
-	jww.INFO.Printf("UnregisterForNotifications()")
-	// // Pull the host from the manage
-	// notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
-	// if !ok {
-	// 	return errors.New("Failed to retrieve host for notification bot")
-	// }
-
-	// // Send the unregister message
-	// _, err := cl.receptionManager.Comms.UnregisterForNotifications(notificationBotHost)
-	// if err != nil {
-	// 	err := errors.Errorf(
-	// 		"RegisterForNotifications: Unable to register for notifications! %s", err)
-	// 	return err
-	// }
-
-	return nil
-}
-
-// Returns true if the cryptographic identity has been registered with
-// the CMIX user discovery agent.
-// Note that clients do not need to perform this step if they use
-// out of band methods to exchange cryptographic identities
-// (e.g., QR codes), but failing to be registered precludes usage
-// of the user discovery mechanism (this may be preferred by user).
-func (c *Client) IsRegistered() bool {
-	jww.INFO.Printf("IsRegistered()")
-	return false
-}
-
-// RegisterIdentity registers an arbitrary username with the user
-// discovery protocol. Returns an error when it cannot connect or
-// the username is already registered.
-func (c *Client) RegisterIdentity(username string) error {
-	jww.INFO.Printf("RegisterIdentity(%s)", username)
-	return nil
-}
-
-// RegisterEmail makes the users email searchable after confirmation.
-// It returns a registration confirmation token to be used with
-// ConfirmRegistration or an error on failure.
-func (c *Client) RegisterEmail(email string) ([]byte, error) {
-	jww.INFO.Printf("RegisterEmail(%s)", email)
-	return nil, nil
-}
-
-// RegisterPhone makes the users phone searchable after confirmation.
-// It returns a registration confirmation token to be used with
-// ConfirmRegistration or an error on failure.
-func (c *Client) RegisterPhone(phone string) ([]byte, error) {
-	jww.INFO.Printf("RegisterPhone(%s)", phone)
-	return nil, nil
-}
-
-// ConfirmRegistration sends the user discovery agent a confirmation
-// token (from register Email/Phone) and code (string sent via Email
-// or SMS to confirm ownership) to confirm ownership.
-func (c *Client) ConfirmRegistration(token, code []byte) error {
-	jww.INFO.Printf("ConfirmRegistration(%s, %s)", token, code)
-	return nil
-}
-
-// GetUser returns the current user Identity for this client. This
-// can be serialized into a byte stream for out-of-band sharing.
-func (c *Client) GetUser() (Contact, error) {
-	jww.INFO.Printf("GetUser()")
-	return Contact{}, nil
-}
-
-// MakeContact creates a contact from a byte stream (i.e., unmarshal's a
-// Contact object), allowing out-of-band import of identities.
-func (c *Client) MakeContact(contactBytes []byte) (Contact, error) {
-	jww.INFO.Printf("MakeContact(%s)", contactBytes)
-	return Contact{}, nil
-}
-
-// GetContact returns a Contact object for the given user id, or
-// an error
-func (c *Client) GetContact(uid []byte) (Contact, error) {
-	jww.INFO.Printf("GetContact(%s)", uid)
-	return Contact{}, nil
-}
-
-// Search accepts a "separator" separated list of search elements with
-// an associated list of searchTypes. It returns a ContactList which
-// allows you to iterate over the found contact objects.
-func (c *Client) Search(data, separator string, searchTypes []byte) []Contact {
-	jww.INFO.Printf("Search(%s, %s, %s)", data, separator, searchTypes)
-	return nil
-}
-
-// SearchWithHandler is a non-blocking search that also registers
-// a callback interface for user disovery events.
-func (c *Client) SearchWithCallback(data, separator string, searchTypes []byte,
-	cb func(results []Contact)) {
-	resultCh := make(chan []Contact, 1)
-	go func(out chan []Contact, data, separator string, srchTypes []byte) {
-		out <- c.Search(data, separator, srchTypes)
-		close(out)
-	}(resultCh, data, separator, searchTypes)
-
-	go func(in chan []Contact, cb func(results []Contact)) {
-		select {
-		case contacts := <-in:
-			cb(contacts)
-			//TODO: Timer
-		}
-	}(resultCh, cb)
-}
-
-// CreateAuthenticatedChannel creates a 1-way authenticated channel
-// so this user can send messages to the desired recipient Contact.
-// To receive confirmation from the remote user, clients must
-// register a listener to do that.
-func (c *Client) CreateAuthenticatedChannel(recipient Contact,
-	payload []byte) error {
-	jww.INFO.Printf("CreateAuthenticatedChannel(%v, %v)",
-		recipient, payload)
-	return nil
-}
-
-// RegisterAuthConfirmationCb registers a callback for channel
-// authentication confirmation events.
-func (c *Client) RegisterAuthConfirmationCb(cb func(contact Contact,
-	payload []byte)) {
-	jww.INFO.Printf("RegisterAuthConfirmationCb(...)")
+// Returns the switchboard for Registration
+func (c *Client) GetSwitchboard() interfaces.Switchboard {
+	return c.switchboard
 }
 
-// RegisterAuthRequestCb registers a callback for channel
-// authentication request events.
-func (c *Client) RegisterAuthRequestCb(cb func(contact Contact,
-	payload []byte)) {
-	jww.INFO.Printf("RegisterAuthRequestCb(...)")
+// Returns the health tracker for registration and polling
+func (c *Client) GetHealth() interfaces.HealthTracker {
+	return c.network.GetHealthTracker()
 }
 
 // RegisterRoundEventsCb registers a callback for round
 // events.
-func (c *Client) RegisterRoundEventsCb(
-	cb func(re *pb.RoundInfo, timedOut bool)) {
-	jww.INFO.Printf("RegisterRoundEventsCb(...)")
+func (c *Client) GetRoundEvents() interfaces.RoundEvents {
+	return c.network.GetInstance().GetRoundEvents()
 }
 
 // ----- Utility Functions -----
diff --git a/api/contact.go b/api/contact.go
index 07f3e6ec0463e08d738cfceb8ce6881b66264d2f..151245d5f2c350505872957d756e9148586f9b19 100644
--- a/api/contact.go
+++ b/api/contact.go
@@ -6,11 +6,35 @@
 
 package api
 
+import jww "github.com/spf13/jwalterweatherman"
+
 import (
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
 )
 
+// GetUser returns the current user Identity for this client. This
+// can be serialized into a byte stream for out-of-band sharing.
+func (c *Client) GetUser() (Contact, error) {
+	jww.INFO.Printf("GetUser()")
+	return Contact{}, nil
+}
+
+// MakeContact creates a contact from a byte stream (i.e., unmarshal's a
+// Contact object), allowing out-of-band import of identities.
+func (c *Client) MakeContact(contactBytes []byte) (Contact, error) {
+	jww.INFO.Printf("MakeContact(%s)", contactBytes)
+	return Contact{}, nil
+}
+
+// GetContact returns a Contact object for the given user id, or
+// an error
+func (c *Client) GetContact(uid []byte) (Contact, error) {
+	jww.INFO.Printf("GetContact(%s)", uid)
+	return Contact{}, nil
+}
+
+
 // Contact implements the Contact interface defined in bindings/interfaces.go,
 type Contact struct {
 	ID            id.ID
diff --git a/api/interfaces.go b/api/interfaces.go
deleted file mode 100644
index 5d8c04419cde6972ac3e253bcce8924a7f6d6e68..0000000000000000000000000000000000000000
--- a/api/interfaces.go
+++ /dev/null
@@ -1,45 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2020 Privategrity Corporation                                   /
-//                                                                             /
-// All rights reserved.                                                        /
-////////////////////////////////////////////////////////////////////////////////
-
-package api
-
-import (
-	"gitlab.com/xx_network/primitives/id"
-)
-
-// Message is a message received from the cMix network in the clear
-// or that has been decrypted using established E2E keys.
-type Message interface {
-	// Returns the message's sender ID, if available
-	GetSender() id.ID
-	GetSenderBytes() []byte
-
-	// Returns the message payload/contents
-	// Parse this with protobuf/whatever according to the message type
-	GetPayload() []byte
-
-	// Returns the message's recipient ID
-	// This is usually your userID but could be an ephemeral/group ID
-	GetRecipient() id.ID
-	GetRecipientBytes() []byte
-
-	// Returns the message's type
-	GetMessageType() int32
-
-	// Returns the message's timestamp in seconds since unix epoc
-	GetTimestamp() int64
-	// Returns the message's timestamp in ns since unix epoc
-	GetTimestampNano() int64
-}
-
-// RoundEvent contains event information for a given round.
-// TODO: This is a half-baked interface and will be filled out later.
-type RoundEvent interface {
-	// GetID returns the round ID for this round.
-	GetID() int
-	// GetStatus returns the status of this round.
-	GetStatus() int
-}
diff --git a/api/notifications.go b/api/notifications.go
new file mode 100644
index 0000000000000000000000000000000000000000..119b675f86ffc0e6f76e39d2dc06d5d77f4a9612
--- /dev/null
+++ b/api/notifications.go
@@ -0,0 +1,51 @@
+package api
+
+import jww "github.com/spf13/jwalterweatherman"
+
+// RegisterForNotifications allows a client to register for push
+// notifications.
+// Note that clients are not required to register for push notifications
+// especially as these rely on third parties (i.e., Firebase *cough*
+// *cough* google's palantir *cough*) that may represent a security
+// risk to the user.
+func (c *Client) RegisterForNotifications(token []byte) error {
+	jww.INFO.Printf("RegisterForNotifications(%s)", token)
+	// // Pull the host from the manage
+	// notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
+	// if !ok {
+	// 	return errors.New("Failed to retrieve host for notification bot")
+	// }
+
+	// // Send the register message
+	// _, err := cl.receptionManager.Comms.RegisterForNotifications(notificationBotHost,
+	// 	&mixmessages.NotificationToken{
+	// 		Token: notificationToken,
+	// 	})
+	// if err != nil {
+	// 	err := errors.Errorf(
+	// 		"RegisterForNotifications: Unable to register for notifications! %s", err)
+	// 	return err
+	// }
+
+	return nil
+}
+
+// UnregisterForNotifications turns of notifications for this client
+func (c *Client) UnregisterForNotifications() error {
+	jww.INFO.Printf("UnregisterForNotifications()")
+	// // Pull the host from the manage
+	// notificationBotHost, ok := cl.receptionManager.Comms.GetHost(&id.NotificationBot)
+	// if !ok {
+	// 	return errors.New("Failed to retrieve host for notification bot")
+	// }
+
+	// // Send the unregister message
+	// _, err := cl.receptionManager.Comms.UnregisterForNotifications(notificationBotHost)
+	// if err != nil {
+	// 	err := errors.Errorf(
+	// 		"RegisterForNotifications: Unable to register for notifications! %s", err)
+	// 	return err
+	// }
+
+	return nil
+}
diff --git a/api/send.go b/api/send.go
new file mode 100644
index 0000000000000000000000000000000000000000..ee11f6da2b32656ee5ff96bc0ca9095d38459a5f
--- /dev/null
+++ b/api/send.go
@@ -0,0 +1,42 @@
+package api
+
+import (
+	"gitlab.com/elixxir/client/interfaces/message"
+	"gitlab.com/elixxir/client/interfaces/params"
+	"gitlab.com/elixxir/primitives/format"
+	"gitlab.com/xx_network/primitives/id"
+	jww "github.com/spf13/jwalterweatherman"
+)
+
+//This holds all functions to send messages over the network
+
+// SendE2E sends an end-to-end payload to the provided recipient with
+// the provided msgType. Returns the list of rounds in which parts of
+// the message were sent or an error if it fails.
+func (c *Client) SendE2E(m message.Send, param params.E2E) ([]id.Round, error) {
+	jww.INFO.Printf("SendE2E(%s, %d. %v)", m.Recipient,
+		m.MessageType, m.Payload)
+	return c.network.SendE2E(m, param)
+}
+
+// SendUnsafe sends an unencrypted payload to the provided recipient
+// with the provided msgType. Returns the list of rounds in which parts
+// of the message were sent or an error if it fails.
+// NOTE: Do not use this function unless you know what you are doing.
+// This function always produces an error message in client logging.
+func (c *Client) SendUnsafe(m message.Send, param params.Unsafe) ([]id.Round,
+	error) {
+	jww.INFO.Printf("SendUnsafe(%s, %d. %v)", m.Recipient,
+		m.MessageType, m.Payload)
+	return c.network.SendUnsafe(m, param)
+}
+
+// SendCMIX sends a "raw" CMIX message payload to the provided
+// recipient. Note that both SendE2E and SendUnsafe call SendCMIX.
+// Returns the round ID of the round the payload was sent or an error
+// if it fails.
+func (c *Client) SendCMIX(msg format.Message, param params.CMIX) (id.Round,
+	error) {
+	jww.INFO.Printf("SendCMIX(%v)", msg)
+	return c.network.SendCMIX(msg, param)
+}
diff --git a/api/userDiscovery.go b/api/userDiscovery.go
new file mode 100644
index 0000000000000000000000000000000000000000..3da6d21fd9aa3f7d59ff2154c9a901cdff2e86a2
--- /dev/null
+++ b/api/userDiscovery.go
@@ -0,0 +1,73 @@
+package api
+
+import jww "github.com/spf13/jwalterweatherman"
+
+// Returns true if the cryptographic identity has been registered with
+// the CMIX user discovery agent.
+// Note that clients do not need to perform this step if they use
+// out of band methods to exchange cryptographic identities
+// (e.g., QR codes), but failing to be registered precludes usage
+// of the user discovery mechanism (this may be preferred by user).
+func (c *Client) IsRegistered() bool {
+	jww.INFO.Printf("IsRegistered()")
+	return false
+}
+
+// RegisterIdentity registers an arbitrary username with the user
+// discovery protocol. Returns an error when it cannot connect or
+// the username is already registered.
+func (c *Client) RegisterIdentity(username string) error {
+	jww.INFO.Printf("RegisterIdentity(%s)", username)
+	return nil
+}
+
+// RegisterEmail makes the users email searchable after confirmation.
+// It returns a registration confirmation token to be used with
+// ConfirmRegistration or an error on failure.
+func (c *Client) RegisterEmail(email string) ([]byte, error) {
+	jww.INFO.Printf("RegisterEmail(%s)", email)
+	return nil, nil
+}
+
+// RegisterPhone makes the users phone searchable after confirmation.
+// It returns a registration confirmation token to be used with
+// ConfirmRegistration or an error on failure.
+func (c *Client) RegisterPhone(phone string) ([]byte, error) {
+	jww.INFO.Printf("RegisterPhone(%s)", phone)
+	return nil, nil
+}
+
+// ConfirmRegistration sends the user discovery agent a confirmation
+// token (from register Email/Phone) and code (string sent via Email
+// or SMS to confirm ownership) to confirm ownership.
+func (c *Client) ConfirmRegistration(token, code []byte) error {
+	jww.INFO.Printf("ConfirmRegistration(%s, %s)", token, code)
+	return nil
+}
+
+// Search accepts a "separator" separated list of search elements with
+// an associated list of searchTypes. It returns a ContactList which
+// allows you to iterate over the found contact objects.
+func (c *Client) Search(data, separator string, searchTypes []byte) []Contact {
+	jww.INFO.Printf("Search(%s, %s, %s)", data, separator, searchTypes)
+	return nil
+}
+
+// SearchWithHandler is a non-blocking search that also registers
+// a callback interface for user disovery events.
+func (c *Client) SearchWithCallback(data, separator string, searchTypes []byte,
+	cb func(results []Contact)) {
+	resultCh := make(chan []Contact, 1)
+	go func(out chan []Contact, data, separator string, srchTypes []byte) {
+		out <- c.Search(data, separator, srchTypes)
+		close(out)
+	}(resultCh, data, separator, searchTypes)
+
+	go func(in chan []Contact, cb func(results []Contact)) {
+		select {
+		case contacts := <-in:
+			cb(contacts)
+			//TODO: Timer
+		}
+	}(resultCh, cb)
+}
diff --git a/interfaces/roundEvents.go b/interfaces/roundEvents.go
new file mode 100644
index 0000000000000000000000000000000000000000..a3f27f76331dec24b73cea6af6bd3c99d1a54514
--- /dev/null
+++ b/interfaces/roundEvents.go
@@ -0,0 +1,32 @@
+package interfaces
+
+import (
+	ds "gitlab.com/elixxir/comms/network/dataStructures"
+	"gitlab.com/elixxir/primitives/states"
+	"gitlab.com/xx_network/primitives/id"
+	"time"
+)
+
+// The round events interface allows the registration of an event which triggers
+// when a round reaches one or more states
+
+type RoundEvents interface {
+	// designates a callback to call on the specified event
+	// rid is the id of the round the event occurs on
+	// callback is the callback the event is triggered on
+	// timeout is the amount of time before an error event is returned
+	// valid states are the states which the event should trigger on
+	AddRoundEvent(rid id.Round, callback ds.RoundEventCallback,
+		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
+
+	// designates a go channel to signal the specified event
+	// rid is the id of the round the event occurs on
+	// eventChan is the channel the event is triggered on
+	// timeout is the amount of time before an error event is returned
+	// valid states are the states which the event should trigger on
+	AddRoundEventChan(rid id.Round, eventChan chan ds.EventReturn,
+		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
+
+	//Allows the un-registration of a round event before it triggers
+	Remove(rid id.Round, e *ds.EventCallback)
+}
diff --git a/interfaces/switchboard.go b/interfaces/switchboard.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ebb9d8b23779c0d8d024d330e078dc1748c6b01
--- /dev/null
+++ b/interfaces/switchboard.go
@@ -0,0 +1,68 @@
+package interfaces
+
+import (
+	"gitlab.com/elixxir/client/interfaces/message"
+	"gitlab.com/elixxir/client/switchboard"
+	"gitlab.com/xx_network/primitives/id"
+)
+
+// public switchboard interface which only allows registration and does not
+// allow speaking messages
+type Switchboard interface {
+	// Registers a new listener. Returns the ID of the new listener.
+	// Keep this around if you want to be able to delete the listener later.
+	//
+	// name is used for debug printing and not checked for uniqueness
+	//
+	// user: 0 for all, or any user ID to listen for messages from a particular
+	// user. 0 can be id.ZeroUser or id.ZeroID
+	// messageType: 0 for all, or any message type to listen for messages of
+	// that type. 0 can be switchboard.AnyType
+	// newListener: something implementing the Listener interface. Do not
+	// pass nil to this.
+	//
+	// If a message matches multiple listeners, all of them will hear the
+	// message.
+	RegisterListener(user *id.ID, messageType message.Type,
+		newListener switchboard.Listener) switchboard.ListenerID
+
+	// Registers a new listener built around the passed function.
+	// Returns the ID of the new listener.
+	// Keep this around if you want to be able to delete the listener later.
+	//
+	// name is used for debug printing and not checked for uniqueness
+	//
+	// user: 0 for all, or any user ID to listen for messages from a particular
+	// user. 0 can be id.ZeroUser or id.ZeroID
+	// messageType: 0 for all, or any message type to listen for messages of
+	// that type. 0 can be switchboard.AnyType
+	// newListener: a function implementing the ListenerFunc function type.
+	// Do not pass nil to this.
+	//
+	// If a message matches multiple listeners, all of them will hear the
+	// message.
+	RegisterFunc(name string, user *id.ID, messageType message.Type,
+		newListener switchboard.ListenerFunc) switchboard.ListenerID
+
+	// Registers a new listener built around the passed channel.
+	// Returns the ID of the new listener.
+	// Keep this around if you want to be able to delete the listener later.
+	//
+	// name is used for debug printing and not checked for uniqueness
+	//
+	// user: 0 for all, or any user ID to listen for messages from a particular
+	// user. 0 can be id.ZeroUser or id.ZeroID
+	// messageType: 0 for all, or any message type to listen for messages of
+	// that type. 0 can be switchboard.AnyType
+	// newListener: an item channel.
+	// Do not pass nil to this.
+	//
+	// If a message matches multiple listeners, all of them will hear the
+	// message.
+	RegisterChannel(name string, user *id.ID, messageType message.Type,
+		newListener chan message.Receive) switchboard.ListenerID
+
+	// Unregister removes the listener with the specified ID so it will no
+	// longer get called
+	Unregister(listenerID switchboard.ListenerID)
+}
diff --git a/network/manager.go b/network/manager.go
index dd7990cc7d54fc9dfc1dd310415d200304159311..75f263b67051ad54275e8d3daab42d0cb90a2af1 100644
--- a/network/manager.go
+++ b/network/manager.go
@@ -87,6 +87,14 @@ func NewManager(session *storage.Session, switchboard *switchboard.Switchboard,
 }
 
 // StartRunners kicks off all network reception goroutines ("threads").
+// Started Threads are:
+//   - Network Follower (/network/follow.go)
+//   - Historical Round Retrieval (/network/rounds/historical.go)
+//	 - Message Retrieval Worker Group (/network/rounds/retrieve.go)
+//	 - Message Handling Worker Group (/network/message/handle.go)
+//	 - Health Tracker (/network/health)
+//	 - Garbled Messages (/network/message/garbled.go)
+//	 - Critical Messages (/network/message/critical.go)
 func (m *manager) Follow() (stoppable.Stoppable, error) {
 
 	if !atomic.CompareAndSwapUint32(m.running, 0, 1) {
diff --git a/network/message/critical.go b/network/message/critical.go
index 164dcf52d65749a86c3845c638b6faa1482b2ab0..238d94c90549ba1c3344f62debe2e819a6c275ba 100644
--- a/network/message/critical.go
+++ b/network/message/critical.go
@@ -10,6 +10,14 @@ import (
 	"time"
 )
 
+// Critical Messages are protocol layer communications that must succeed. These
+// are added to the persistent critical messages store.  This thread waits for
+// network access to move from unhealthy to healthy and the sends all critical
+// messages.
+// Health is tracked by registering with the Health
+// Tracker (/network/Health/Tracker.g0)
+
+//Thread loop for processing critical messages
 func (m *Manager) processCriticalMessages(quitCh <-chan struct{}) {
 	done := false
 	for !done {
@@ -24,6 +32,7 @@ func (m *Manager) processCriticalMessages(quitCh <-chan struct{}) {
 	}
 }
 
+// processes all critical messages
 func (m *Manager) criticalMessages() {
 	critMsgs := m.Session.GetCriticalMessages()
 	//try to send every message in the critical messages buffer in paralell
diff --git a/network/message/sendCmix.go b/network/message/sendCmix.go
index afe860183fee453e4e8c6ebddb3273f3ef7b6faf..c60cab6aa257d7a11d6a01666d2f0c31c2b22f4a 100644
--- a/network/message/sendCmix.go
+++ b/network/message/sendCmix.go
@@ -13,6 +13,9 @@ import (
 	"time"
 )
 
+// WARNING: Potentially Unsafe
+// Payloads send are not End to End encrypted, MetaData is NOT protected with
+// this call, see SendE2E for End to End encryption and full privacy protection
 // Internal SendCmix which bypasses the network check, will attempt to send to
 // the network without checking state. It has a built in retry system which can
 // be configured through the params object.
diff --git a/network/message/sendUnsafe.go b/network/message/sendUnsafe.go
index 2cabff6fcc194bffe01fc05648af666029d079f0..92c3fbbf29f9cff68aaf585c4eca268184733d60 100644
--- a/network/message/sendUnsafe.go
+++ b/network/message/sendUnsafe.go
@@ -11,6 +11,15 @@ import (
 	"time"
 )
 
+// WARNING: Unsafe
+// Payloads are not End to End encrypted, MetaData is NOT protected with
+// this call, see SendE2E for End to End encryption and full privacy protection
+// Internal SendUnsafe which bypasses the network check, will attempt to send to
+// the network without checking state.
+// This partitions payloads into multi-part messages but does NOT end to encrypt
+// them
+// Sends using SendCMIX and returns a list of rounds the messages are in. Will
+// return an error if a single part of the message fails to send.
 func (m *Manager) SendUnsafe(msg message.Send, param params.Unsafe) ([]id.Round, error) {
 
 	//timestamp the message