diff --git a/bindings/group.go b/bindings/group.go
index a1f32b34e9c613bbb4357f6c2705ee930a7d3c01..e0da4aff7b437dac7de98d07957a0da14b6888d9 100644
--- a/bindings/group.go
+++ b/bindings/group.go
@@ -124,8 +124,8 @@ func (g *GroupChat) Send(groupIdBytes, message []byte) (*GroupSendReport, error)
 		return nil, errors.Errorf("Failed to unmarshal group ID: %+v", err)
 	}
 
-	round, timestamp, err := g.m.Send(groupID, message)
-	return &GroupSendReport{round, timestamp}, err
+	round, timestamp, msgID, err := g.m.Send(groupID, message)
+	return &GroupSendReport{round, timestamp, msgID}, err
 }
 
 // GetGroups returns an IdList containing a list of group IDs that the user is a
@@ -239,6 +239,7 @@ func (ngr *NewGroupReport) Unmarshal(b []byte) error {
 type GroupSendReport struct {
 	roundID   id.Round
 	timestamp time.Time
+	messageID group.MessageID
 }
 
 // GetRoundID returns the ID of the round that the send occurred on.
@@ -257,6 +258,11 @@ func (gsr *GroupSendReport) GetTimestampMS() int64 {
 	return int64(ts)
 }
 
+// GetMessageID returns the ID of the round that the send occurred on.
+func (gsr *GroupSendReport) GetMessageID() []byte {
+	return gsr.messageID[:]
+}
+
 ////
 // Group Structure
 ////
diff --git a/cmd/group.go b/cmd/group.go
index b973fb5c7f2b7addcb12a26c2a59b7b4c1524c22..1c7365921187bc6fda2754b2950498709c5f46f9 100644
--- a/cmd/group.go
+++ b/cmd/group.go
@@ -218,7 +218,7 @@ func sendGroup(groupIdString string, msg []byte, gm *groupChat.Manager) {
 
 	jww.INFO.Printf("Sending to group %s message %q", groupID, msg)
 
-	rid, timestamp, err := gm.Send(groupID, msg)
+	rid, timestamp, _, err := gm.Send(groupID, msg)
 	if err != nil {
 		jww.FATAL.Panicf("Sending message to group %s: %+v", groupID, err)
 	}
diff --git a/groupChat/send.go b/groupChat/send.go
index 868d420134b6ebb79c0687f58648311af6445559..e626e1959dea8a47c44f462c38fba7b68521353d 100644
--- a/groupChat/send.go
+++ b/groupChat/send.go
@@ -37,15 +37,15 @@ const (
 
 // Send sends a message to all group members using Client.SendManyCMIX. The
 // send fails if the message is too long.
-func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time,
+func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time, group.MessageID,
 	error) {
 	// Get the current time stripped of the monotonic clock
 	timeNow := netTime.Now().Round(0)
 
 	// Create a cMix message for each group member
-	messages, err := m.createMessages(groupID, message, timeNow)
+	messages, msgID, err := m.createMessages(groupID, message, timeNow)
 	if err != nil {
-		return 0, time.Time{}, errors.Errorf(newCmixMsgErr, err)
+		return 0, time.Time{}, group.MessageID{}, errors.Errorf(newCmixMsgErr, err)
 	}
 
 	param := params.GetDefaultCMIX()
@@ -53,28 +53,38 @@ func (m *Manager) Send(groupID *id.ID, message []byte) (id.Round, time.Time,
 
 	rid, _, err := m.net.SendManyCMIX(messages, param)
 	if err != nil {
-		return 0, time.Time{},
+		return 0, time.Time{}, group.MessageID{},
 			errors.Errorf(sendManyCmixErr, m.gs.GetUser().ID, groupID, err)
 	}
 
 	jww.DEBUG.Printf("Sent message to %d members in group %s at %s.",
 		len(messages), groupID, timeNow)
 
-	return rid, timeNow, nil
+	return rid, timeNow, msgID, nil
 }
 
 // createMessages generates a list of cMix messages and a list of corresponding
 // recipient IDs.
 func (m *Manager) createMessages(groupID *id.ID, msg []byte, timestamp time.Time) (
-	[]message.TargetedCmixMessage, error) {
+	[]message.TargetedCmixMessage, group.MessageID, error) {
+
+	//make the message ID
+	cmixMsg := format.NewMessage(m.store.Cmix().GetGroup().GetP().ByteLen())
+	_, intlMsg, err := newMessageParts(cmixMsg.ContentsSize())
+	if err != nil {
+		return nil, group.MessageID{},errors.WithMessage(err,"Failed to make message parts for message ID")
+	}
+	messageID := group.NewMessageID(groupID, setInternalPayload(intlMsg, timestamp, m.gs.GetUser().ID, msg))
 
 	g, exists := m.gs.Get(groupID)
 	if !exists {
-		return []message.TargetedCmixMessage{},
+		return []message.TargetedCmixMessage{}, group.MessageID{},
 			errors.Errorf(newNoGroupErr, groupID)
 	}
 
-	return m.newMessages(g, msg, timestamp)
+	NewMessages, err := m.newMessages(g, msg, timestamp)
+
+	return NewMessages, messageID, err
 }
 
 // newMessages is a private function that allows the passing in of a timestamp
diff --git a/groupChat/send_test.go b/groupChat/send_test.go
index 8fd29ba8c60719ef6f0ca2eff8c1d39049ef1c42..2d6940c3a69dbe3b894481e738d6fbb1d7974e45 100644
--- a/groupChat/send_test.go
+++ b/groupChat/send_test.go
@@ -30,7 +30,7 @@ func TestManager_Send(t *testing.T) {
 	messageBytes := []byte("Group chat message.")
 	sender := m.gs.GetUser().DeepCopy()
 
-	_, _, err := m.Send(g.ID, messageBytes)
+	_, _, _, err := m.Send(g.ID, messageBytes)
 	if err != nil {
 		t.Errorf("Send() returned an error: %+v", err)
 	}
@@ -110,7 +110,7 @@ func TestManager_Send_CmixMessageError(t *testing.T) {
 	expectedErr := strings.SplitN(newCmixMsgErr, "%", 2)[0]
 
 	// Send message
-	_, _, err := m.Send(g.ID, make([]byte, 400))
+	_, _, _, err := m.Send(g.ID, make([]byte, 400))
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("Send() failed to return the expected error."+
 			"\nexpected: %s\nreceived: %+v", expectedErr, err)
@@ -125,7 +125,7 @@ func TestManager_Send_SendManyCMIXError(t *testing.T) {
 	expectedErr := strings.SplitN(sendManyCmixErr, "%", 2)[0]
 
 	// Send message
-	_, _, err := m.Send(g.ID, []byte("message"))
+	_, _, _, err := m.Send(g.ID, []byte("message"))
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("Send() failed to return the expected error."+
 			"\nexpected: %s\nreceived: %+v", expectedErr, err)
@@ -145,7 +145,7 @@ func TestManager_createMessages(t *testing.T) {
 
 	testMsg := []byte("Test group message.")
 	sender := m.gs.GetUser()
-	messages, err := m.createMessages(g.ID, testMsg, netTime.Now())
+	messages, _, err := m.createMessages(g.ID, testMsg, netTime.Now())
 	if err != nil {
 		t.Errorf("createMessages() returned an error: %+v", err)
 	}
@@ -205,7 +205,7 @@ func TestManager_createMessages_InvalidGroupIdError(t *testing.T) {
 	m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
 
 	// Read message and make sure the error is expected
-	_, err := m.createMessages(
+	_, _, err := m.createMessages(
 		id.NewIdFromString("invalidID", id.Group, t), nil, time.Time{})
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("createMessages() did not return the expected error."+