diff --git a/auth/utils_test.go b/auth/utils_test.go
index 0fd05d2aecffd239ee13ae6f09dd4725c42a3bb3..b2c11bb4c04e822c86f4e6f9d7c29a7d5422ad0e 100644
--- a/auth/utils_test.go
+++ b/auth/utils_test.go
@@ -13,7 +13,6 @@ import (
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/cyclic"
-	cryptoE2e "gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/primitives/states"
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/large"
@@ -61,9 +60,8 @@ func (m mockE2eHandler) StartProcesses() (stoppable.Stoppable, error) {
 }
 
 func (m mockE2eHandler) SendE2E(mt catalog.MessageType, recipient *id.ID,
-	payload []byte, params e2e.Params) ([]id.Round, cryptoE2e.MessageID,
-	time.Time, cryptoE2e.KeyResidue, error) {
-	return nil, cryptoE2e.MessageID{}, time.Time{}, cryptoE2e.KeyResidue{}, nil
+	payload []byte, params e2e.Params) (e2e.SendReport, error) {
+	return e2e.SendReport{}, nil
 }
 
 func (m mockE2eHandler) RegisterListener(senderID *id.ID,
diff --git a/bindings/e2eHandler.go b/bindings/e2eHandler.go
index 89a2127e8e253508bef6ddc319d10e4cd4e4dfe4..2e7d002599bdee81b0894076a43a031e220f5a86 100644
--- a/bindings/e2eHandler.go
+++ b/bindings/e2eHandler.go
@@ -135,17 +135,17 @@ func (e *E2e) SendE2E(messageType int, recipientId, payload,
 		return nil, err
 	}
 
-	roundIds, messageId, ts, keyResidue, err := e.api.GetE2E().SendE2E(
+	sendReport, err := e.api.GetE2E().SendE2E(
 		catalog.MessageType(messageType), recipient, payload, params)
 	if err != nil {
 		return nil, err
 	}
 
 	result := E2ESendReport{
-		RoundsList: makeRoundsList(roundIds...),
-		MessageID:  messageId.Marshal(),
-		Timestamp:  ts.UnixNano(),
-		KeyResidue: keyResidue.Marshal(),
+		RoundsList: makeRoundsList(sendReport.RoundList...),
+		MessageID:  sendReport.MessageId.Marshal(),
+		Timestamp:  sendReport.SentTime.UnixNano(),
+		KeyResidue: sendReport.KeyResidue.Marshal(),
 	}
 	return json.Marshal(result)
 }
diff --git a/bindings/json_test.go b/bindings/json_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b42bc6806ab14d52f7a731513e72d4234164d084
--- /dev/null
+++ b/bindings/json_test.go
@@ -0,0 +1,33 @@
+package bindings
+
+import (
+	"encoding/json"
+	"gitlab.com/elixxir/crypto/e2e"
+	"math/rand"
+	"testing"
+	"time"
+)
+
+func TestName(t *testing.T) {
+	rl := []uint64{1, 4, 9}
+	prng := rand.New(rand.NewSource(42))
+	rfp := make([]byte, 32)
+	prng.Read(rfp)
+	mid := e2e.NewMessageID(rfp, prng.Uint64())
+
+	randData := make([]byte, 32)
+	prng.Read(randData)
+	k := e2e.Key{}
+	copy(k[:], randData)
+	kr := e2e.NewKeyResidue(k)
+
+	report := E2ESendReport{
+		RoundsList: RoundsList{rl},
+		MessageID:  mid.Marshal(),
+		Timestamp:  time.Now().UnixNano(),
+		KeyResidue: kr.Marshal(),
+	}
+
+	marshal, _ := json.Marshal(report)
+	t.Logf("%s", marshal)
+}
diff --git a/cmd/root.go b/cmd/root.go
index 6fe4ee7788a006b8e28e01c1df020f4d028fdef2..56074b3d60a38f1f6f1322251a92a15fcba85987 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -14,6 +14,7 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"gitlab.com/elixxir/client/e2e"
 	"io/ioutil"
 	"log"
 	"os"
@@ -288,8 +289,10 @@ var rootCmd = &cobra.Command{
 								e2eParams.Base)
 						} else {
 							e2eParams.Base.DebugTag = "cmd.E2E"
-							roundIDs, _, _, _, err = user.GetE2E().SendE2E(mt,
+							var sendReport e2e.SendReport
+							sendReport, err = user.GetE2E().SendE2E(mt,
 								recipient, payload, e2eParams.Base)
+							roundIDs = sendReport.RoundList
 						}
 						if err != nil {
 							jww.FATAL.Panicf("%+v", err)
diff --git a/connect/connect.go b/connect/connect.go
index 8c20cf5693f653828fd60a56bfe11a86299acfe2..83896dbc37adde256af6c49818f63e3801f1206e 100644
--- a/connect/connect.go
+++ b/connect/connect.go
@@ -22,8 +22,6 @@ import (
 	"gitlab.com/elixxir/client/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/crypto/contact"
-	"gitlab.com/elixxir/crypto/e2e"
-	"gitlab.com/xx_network/primitives/id"
 )
 
 var alreadyClosedErr = errors.New("connection is closed")
@@ -43,7 +41,7 @@ type Connection interface {
 	// SendE2E is a wrapper for sending specifically to the Connection's
 	// partner.Manager
 	SendE2E(mt catalog.MessageType, payload []byte, params clientE2e.Params) (
-		[]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error)
+		clientE2e.SendReport, error)
 
 	// RegisterListener is used for E2E reception
 	// and allows for reading data sent from the partner.Manager
@@ -221,9 +219,9 @@ func (h *handler) GetPartner() partner.Manager {
 // SendE2E is a wrapper for sending specifically to the Connection's
 // partner.Manager.
 func (h *handler) SendE2E(mt catalog.MessageType, payload []byte,
-	params clientE2e.Params) ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+	params clientE2e.Params) (clientE2e.SendReport, error) {
 	if h.isClosed() {
-		return nil, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, alreadyClosedErr
+		return clientE2e.SendReport{}, alreadyClosedErr
 	}
 
 	h.updateLastUse(netTime.Now())
diff --git a/e2e/critical.go b/e2e/critical.go
index 30dc3c05ffb13373888c1f7866137a13b3abf19f..95c4af3fb7e886654261a1b5ede631eb8a6e2dd9 100644
--- a/e2e/critical.go
+++ b/e2e/critical.go
@@ -9,7 +9,6 @@ import (
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage/versioned"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/states"
 	"gitlab.com/xx_network/primitives/id"
@@ -29,7 +28,7 @@ type roundEventRegistrar interface {
 // anonymous function to include the structures from manager that critical is
 // not aware of.
 type criticalSender func(mt catalog.MessageType, recipient *id.ID,
-	payload []byte, params Params) ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error)
+	payload []byte, params Params) (SendReport, error)
 
 // critical is a structure that allows the auto resending of messages that must
 // be received.
@@ -138,11 +137,11 @@ func (c *critical) evaluate(stop *stoppable.Single) {
 				format.DigestContents(payload))
 
 			// Send the message
-			round, _, _, _, err := c.send(mt, recipient, payload,
+			sendReport, err := c.send(mt, recipient, payload,
 				params)
 
 			// Pass to the handler
-			c.handle(mt, recipient, payload, round, err)
+			c.handle(mt, recipient, payload, sendReport.RoundList, err)
 		}(mt, recipient, payload, params)
 	}
 
diff --git a/e2e/interface.go b/e2e/interface.go
index e78997fbb67909eb6a986d52d1223ccc4d161013..138dbf9eb023e5e53df2863a584878810d1b60dd 100644
--- a/e2e/interface.go
+++ b/e2e/interface.go
@@ -12,7 +12,6 @@ import (
 	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/xx_network/primitives/id"
 )
 
@@ -35,7 +34,7 @@ type Handler interface {
 	// Will return an error if the network is not healthy or in
 	// the event of a failed send
 	SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte,
-		params Params) ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error)
+		params Params) (SendReport, error)
 
 	/* === Reception ==================================================== */
 
diff --git a/e2e/manager.go b/e2e/manager.go
index eda1ea43ba0c1b36d63bf9dae63b99d03945ebf6..a426e9eada7daa937342411e485f5a046ba33f9e 100644
--- a/e2e/manager.go
+++ b/e2e/manager.go
@@ -4,10 +4,8 @@ import (
 	"bytes"
 	"encoding/base64"
 	"encoding/json"
-	"sync"
-	"time"
-
 	jww "github.com/spf13/jwalterweatherman"
+	"sync"
 
 	"gitlab.com/xx_network/primitives/netTime"
 
@@ -23,7 +21,6 @@ import (
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
 )
@@ -214,8 +211,7 @@ func (m *manager) StartProcesses() (stoppable.Stoppable, error) {
 
 	rekeySendFunc := func(mt catalog.MessageType,
 		recipient *id.ID, payload []byte,
-		cmixParams cmix.CMIXParams) (
-		[]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+		cmixParams cmix.CMIXParams) (SendReport, error) {
 		// FIXME: we should have access to the e2e params here...
 		par := GetDefaultParams()
 		par.CMIXParams = cmixParams
@@ -284,14 +280,15 @@ func (m *manager) DeletePartnerNotify(partnerId *id.ID, params Params) error {
 	m.DeletePartnerCallbacks(partnerId)
 
 	// Send closing E2E message
-	rounds, msgID, timestamp, _, err := sendFunc()
+
+	sendReport, err := sendFunc()
 	if err != nil {
 		jww.ERROR.Printf("Failed to send %s E2E message to %s: %+v",
 			catalog.E2eClose, partnerId, err)
 	} else {
 		jww.INFO.Printf(
 			"Sent %s E2E message to %s on rounds %v with message ID %s at %s",
-			catalog.E2eClose, partnerId, rounds, msgID, timestamp)
+			catalog.E2eClose, partnerId, sendReport.RoundList, sendReport.MessageId, sendReport.SentTime)
 	}
 
 	return nil
diff --git a/e2e/rekey/exchange.go b/e2e/rekey/exchange.go
index db3ae9d8e79b7451b3a3ffa3b691f6173aa8bce8..4ffbad5ca9e3983d1455a61352de6ccc24dfafee 100644
--- a/e2e/rekey/exchange.go
+++ b/e2e/rekey/exchange.go
@@ -10,18 +10,16 @@ package rekey
 import (
 	"gitlab.com/elixxir/client/catalog"
 	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/e2e"
 	"gitlab.com/elixxir/client/e2e/ratchet"
 	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/xx_network/primitives/id"
-	"time"
 )
 
 type E2eSender func(mt catalog.MessageType, recipient *id.ID, payload []byte,
-	cmixParams cmix.CMIXParams) (
-	[]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error)
+	cmixParams cmix.CMIXParams) (e2e.SendReport, error)
 
 func Start(switchboard *receive.Switchboard, ratchet *ratchet.Ratchet,
 	sender E2eSender, net cmix.Client, grp *cyclic.Group, params Params) (stoppable.Stoppable, error) {
diff --git a/e2e/rekey/rekey.go b/e2e/rekey/rekey.go
index 8bb3aa94b8b15c64496e21b71cf7b87258b4530f..3d2cdfca774503ea68d6d0bb217c73ffbeba34dc 100644
--- a/e2e/rekey/rekey.go
+++ b/e2e/rekey/rekey.go
@@ -126,7 +126,7 @@ func negotiate(instance *commsNetwork.Instance, grp *cyclic.Group, sendE2E E2eSe
 	params.DebugTag = "kx.Request"
 
 	// fixme: should this use the key residue?
-	rounds, msgID, _, _, err := sendE2E(param.Trigger, sess.GetPartner(),
+	sendReport, err := sendE2E(param.Trigger, sess.GetPartner(),
 		payload, params)
 	// If the send fails, returns the error so it can be handled. The caller
 	// should ensure the calling session is in a state where the Rekey will
@@ -138,18 +138,18 @@ func negotiate(instance *commsNetwork.Instance, grp *cyclic.Group, sendE2E E2eSe
 	}
 
 	//create the runner which will handle the result of sending the messages
-	sendResults := make(chan ds.EventReturn, len(rounds))
+	sendResults := make(chan ds.EventReturn, len(sendReport.RoundList))
 
 	//Register the event for all rounds
 	roundEvents := instance.GetRoundEvents()
-	for _, r := range rounds {
+	for _, r := range sendReport.RoundList {
 		roundEvents.AddRoundEventChan(r, sendResults, sendTimeout,
 			states.COMPLETED, states.FAILED)
 	}
 
 	//Wait until the result tracking responds
 	success, numRoundFail, numTimeOut := cmix.TrackResults(sendResults,
-		len(rounds))
+		len(sendReport.RoundList))
 
 	// If a single partition of the Key Negotiation request does not
 	// transmit, the partner cannot read the result. Log the error and set
@@ -158,14 +158,14 @@ func negotiate(instance *commsNetwork.Instance, grp *cyclic.Group, sendE2E E2eSe
 		_ = sess.TrySetNegotiationStatus(session.Unconfirmed)
 		return errors.Errorf("[REKEY] Key Negotiation rekey for %s failed to "+
 			"transmit %v/%v paritions: %v round failures, %v timeouts, msgID: %s",
-			sess, numRoundFail+numTimeOut, len(rounds), numRoundFail,
-			numTimeOut, msgID)
+			sess, numRoundFail+numTimeOut, len(sendReport.RoundList), numRoundFail,
+			numTimeOut, sendReport.MessageId)
 	}
 
 	// otherwise, the transmission is a success and this should be denoted
 	// in the session and the log
 	jww.INFO.Printf("[REKEY] Key Negotiation rekey transmission for %s, msgID %s successful",
-		sess, msgID)
+		sess, sendReport.MessageId)
 	err = sess.TrySetNegotiationStatus(session.Sent)
 	if err != nil {
 		if sess.NegotiationStatus() == session.NewSessionTriggered {
diff --git a/e2e/rekey/trigger.go b/e2e/rekey/trigger.go
index d389d34885cd34e4238e79b6a1d6ccade0c1a97a..4f62828c669c4c34c6500747fca1af4bb7922aee 100644
--- a/e2e/rekey/trigger.go
+++ b/e2e/rekey/trigger.go
@@ -127,8 +127,8 @@ func handleTrigger(ratchet *ratchet.Ratchet, sender E2eSender,
 	params := cmix.GetDefaultCMIXParams()
 	params.Critical = true
 	//ignore results, the passed sender interface makes it a critical message
-	// fixme: sould this use the key residue
-	_, _, _, _, _ = sender(param.Confirm, request.Sender, payload,
+	// fixme: should this ignore the error as well?
+	_, _ = sender(param.Confirm, request.Sender, payload,
 		params)
 
 	return nil
diff --git a/e2e/rekey/trigger_test.go b/e2e/rekey/trigger_test.go
index 8e9ab6658eb627babb1dd9acacd0150222f1a71c..ba41dff0e1e179c746265260a5328c8312772465 100644
--- a/e2e/rekey/trigger_test.go
+++ b/e2e/rekey/trigger_test.go
@@ -119,7 +119,8 @@ func TestHandleTrigger(t *testing.T) {
 	rekeyParams := GetDefaultParams()
 	stop := stoppable.NewSingle("stoppable")
 	rekeyParams.RoundTimeout = 0 * time.Second
-	err = handleTrigger(r, testSendE2E, &mockNetManager{}, grp, receiveMsg, rekeyParams, stop)
+	err = handleTrigger(r, testSendE2E, &mockNetManager{}, grp, receiveMsg,
+		rekeyParams, stop)
 	if err != nil {
 		t.Errorf("Handle trigger error: %v", err)
 	}
diff --git a/e2e/rekey/utils_test.go b/e2e/rekey/utils_test.go
index f3de03391bd845700b5347d34bd8c7cf65a55f61..dac9236a728da1f95793e2f68d273bc0df3fc5dc 100644
--- a/e2e/rekey/utils_test.go
+++ b/e2e/rekey/utils_test.go
@@ -8,6 +8,7 @@
 package rekey
 
 import (
+	e2e2 "gitlab.com/elixxir/client/e2e"
 	"math/rand"
 	"testing"
 	"time"
@@ -27,7 +28,6 @@ import (
 	network2 "gitlab.com/elixxir/comms/network"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/comms/connect"
@@ -74,7 +74,7 @@ func genSidhKeys() (*sidh.PrivateKey, *sidh.PublicKey, *sidh.PrivateKey, *sidh.P
 
 func testSendE2E(mt catalog.MessageType, recipient *id.ID,
 	payload []byte, cmixParams cmix.CMIXParams) (
-	[]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+	e2e2.SendReport, error) {
 	rounds := []id.Round{id.Round(0), id.Round(1), id.Round(2)}
 	alicePartner, err := r.GetPartner(aliceID)
 	if err != nil {
@@ -110,7 +110,9 @@ func testSendE2E(mt catalog.MessageType, recipient *id.ID,
 
 	bobSwitchboard.Speak(confirmMessage)
 
-	return rounds, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, nil
+	return e2e2.SendReport{
+		RoundList: rounds,
+	}, nil
 }
 
 var pub = "-----BEGIN CERTIFICATE-----\n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\n-----END CERTIFICATE-----\n"
diff --git a/e2e/sendE2E.go b/e2e/sendE2E.go
index 9d72b3aa2f7a85027efd68faa15aaef9123c4ca6..fbe407013982bd1df9b15ec7a43f612885312030 100644
--- a/e2e/sendE2E.go
+++ b/e2e/sendE2E.go
@@ -23,18 +23,24 @@ type SendReport struct {
 	// RoundList is the list of rounds which the message payload
 	// is sent.
 	RoundList []id.Round
+
+	// MessageId is the ID of the message sent.
 	MessageId e2e.MessageID
 
 	// SentTime is the time in which the message was sent.
 	// More specifically it is when SendE2e is called.
 	SentTime time.Time
+
+	// KeyResidue is the residue of the key used for the first partition of the
+	// message payload. The residue is a hash of the key and a salt.
+	KeyResidue e2e.KeyResidue
 }
 
 func (m *manager) SendE2E(mt catalog.MessageType, recipient *id.ID,
-	payload []byte, params Params) ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+	payload []byte, params Params) (SendReport, error) {
 
 	if !m.net.IsHealthy() {
-		return nil, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{},
+		return SendReport{},
 			errors.New("cannot sendE2E when network is not healthy")
 	}
 
@@ -46,18 +52,18 @@ func (m *manager) SendE2E(mt catalog.MessageType, recipient *id.ID,
 		params.Critical = false
 	}
 
-	rounds, msgID, t, residue, err := m.sendE2E(mt, recipient, payload, params)
+	sendReport, err := m.sendE2E(mt, recipient, payload, params)
 
 	if handleCritical {
-		m.crit.handle(mt, recipient, payload, rounds, err)
+		m.crit.handle(mt, recipient, payload, sendReport.RoundList, err)
 	}
-	return rounds, msgID, t, residue, err
+	return sendReport, err
 
 }
 
 // sendE2eFn contains a prepared sendE2E operation and sends an E2E message when
 // called, returning the results of the send.
-type sendE2eFn func() ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error)
+type sendE2eFn func() (SendReport, error)
 
 // prepareSendE2E makes a prepared function that does the e2e send.
 // This is so that when doing deletePartner we can prepare the send before
@@ -102,8 +108,7 @@ func (m *manager) prepareSendE2E(mt catalog.MessageType, recipient *id.ID,
 		if mt != catalog.KeyExchangeTrigger {
 			// Check if any rekeys need to happen and trigger them
 			rekeySendFunc := func(mt catalog.MessageType, recipient *id.ID,
-				payload []byte, cmixParams cmix.CMIXParams) (
-				[]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+				payload []byte, cmixParams cmix.CMIXParams) (SendReport, error) {
 				par := params
 				par.CMIXParams = cmixParams
 				return m.SendE2E(mt, recipient, payload, par)
@@ -166,7 +171,7 @@ func (m *manager) prepareSendE2E(mt catalog.MessageType, recipient *id.ID,
 		sendFuncs = append(sendFuncs, thisSendFunc)
 	}
 
-	sendE2E = func() ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+	sendE2E = func() (SendReport, error) {
 		for i := range sendFuncs {
 			sendFuncs[i]()
 		}
@@ -177,7 +182,7 @@ func (m *manager) prepareSendE2E(mt catalog.MessageType, recipient *id.ID,
 		if numFail > 0 {
 			jww.INFO.Printf("Failed to E2E send %d/%d to %s",
 				numFail, len(partitions), recipient)
-			return nil, e2e.MessageID{}, time.Time{}, keyResidue, errors.Errorf(
+			return SendReport{}, errors.Errorf(
 				"Failed to E2E send %v/%v sub payloads: %s",
 				numFail, len(partitions), errRtn)
 		} else {
@@ -188,16 +193,21 @@ func (m *manager) prepareSendE2E(mt catalog.MessageType, recipient *id.ID,
 		jww.INFO.Printf("Successful E2E Send of %d messages to %s with msgID %s",
 			len(partitions), recipient, msgID)
 
-		return roundIds, msgID, ts, keyResidue, nil
+		return SendReport{
+			RoundList:  roundIds,
+			MessageId:  msgID,
+			SentTime:   ts,
+			KeyResidue: keyResidue,
+		}, nil
 	}
 	return sendE2E, nil
 }
 
 func (m *manager) sendE2E(mt catalog.MessageType, recipient *id.ID,
-	payload []byte, params Params) ([]id.Round, e2e.MessageID, time.Time, e2e.KeyResidue, error) {
+	payload []byte, params Params) (SendReport, error) {
 	sendFunc, err := m.prepareSendE2E(mt, recipient, payload, params)
 	if err != nil {
-		return nil, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, err
+		return SendReport{}, err
 	}
 	return sendFunc()
 }
diff --git a/e2e/sendE2E_test.go b/e2e/sendE2E_test.go
index 26a25d1933181c31e6f0f40acdd888bab3e9bffe..12f89ce15a2fdf692f8b82ceecddebf7e8bd25f8 100644
--- a/e2e/sendE2E_test.go
+++ b/e2e/sendE2E_test.go
@@ -107,7 +107,7 @@ func Test_manager_SendE2E_Smoke(t *testing.T) {
 
 	payload := []byte("My Payload")
 	p := GetDefaultParams()
-	_, _, _, _, err = m1.SendE2E(catalog.NoType, partnerID, payload, p)
+	_, err = m1.SendE2E(catalog.NoType, partnerID, payload, p)
 	if err != nil {
 		t.Errorf("SendE2E failed: %+v", err)
 	}
diff --git a/groupChat/e2eManager_test.go b/groupChat/e2eManager_test.go
index 7bee5fa08696e99c951cc6d1b3bc67bfc2e21d1f..19775d9f922c84b3857887498ffc768551f95dce 100644
--- a/groupChat/e2eManager_test.go
+++ b/groupChat/e2eManager_test.go
@@ -11,7 +11,6 @@ import (
 	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/xx_network/primitives/id"
 	"sync"
 	"testing"
@@ -65,16 +64,15 @@ func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
 }
 
 func (tnm *testE2eManager) SendE2E(_ catalog.MessageType, recipient *id.ID,
-	payload []byte, _ clientE2E.Params) ([]id.Round, e2e.MessageID, time.Time,
-	e2e.KeyResidue, error) {
+	payload []byte, _ clientE2E.Params) (clientE2E.SendReport, error) {
 	tnm.Lock()
 	defer tnm.Unlock()
 
 	tnm.errSkip++
 	if tnm.sendErr == 1 {
-		return nil, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, errors.New("SendE2E error")
+		return clientE2E.SendReport{}, errors.New("SendE2E error")
 	} else if tnm.sendErr == 2 && tnm.errSkip%2 == 0 {
-		return nil, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, errors.New("SendE2E error")
+		return clientE2E.SendReport{}, errors.New("SendE2E error")
 	}
 
 	tnm.e2eMessages = append(tnm.e2eMessages, testE2eMessage{
@@ -82,7 +80,7 @@ func (tnm *testE2eManager) SendE2E(_ catalog.MessageType, recipient *id.ID,
 		Payload:   payload,
 	})
 
-	return []id.Round{0, 1, 2, 3}, e2e.MessageID{}, time.Time{}, e2e.KeyResidue{}, nil
+	return clientE2E.SendReport{RoundList: []id.Round{0, 1, 2, 3}}, nil
 }
 
 func (*testE2eManager) RegisterListener(*id.ID, catalog.MessageType, receive.Listener) receive.ListenerID {
diff --git a/groupChat/interface.go b/groupChat/interface.go
index 28d7f4e3a305dd04f1408159943c1c606fe68a9e..bf0469ccd1db5535ddeef7a947038696f44acd4c 100644
--- a/groupChat/interface.go
+++ b/groupChat/interface.go
@@ -32,7 +32,6 @@ import (
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
-	crypto "gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/xx_network/primitives/id"
@@ -126,7 +125,7 @@ type groupCmix interface {
 // needed by GroupChat
 type groupE2eHandler interface {
 	SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte,
-		params e2e.Params) ([]id.Round, crypto.MessageID, time.Time, crypto.KeyResidue, error)
+		params e2e.Params) (e2e.SendReport, error)
 	RegisterListener(senderID *id.ID, messageType catalog.MessageType,
 		newListener receive.Listener) receive.ListenerID
 	AddService(tag string, processor message.Processor) error
diff --git a/ud/mockE2e_test.go b/ud/mockE2e_test.go
index 33b1e543aec380a1d1effeeb41371eaa1773b453..86a880401c775353ea16d59a0c316e389e42a505 100644
--- a/ud/mockE2e_test.go
+++ b/ud/mockE2e_test.go
@@ -15,7 +15,6 @@ import (
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/client/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
-	cryptoE2e "gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/signature/rsa"
@@ -109,7 +108,7 @@ func (m mockE2eHandler) StartProcesses() (stoppable.Stoppable, error) {
 	panic("implement me")
 }
 
-func (m mockE2eHandler) SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte, params e2e.Params) ([]id.Round, cryptoE2e.MessageID, time.Time, cryptoE2e.KeyResidue, error) {
+func (m mockE2eHandler) SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte, params e2e.Params) (e2e.SendReport, error) {
 	//TODO implement me
 	panic("implement me")
 }