Skip to main content

Encrypted Message

Mixin is very concerned about personal privacy. In the old day, messages between users and bots were not encrypted. Now we do some changes.

Overview of Encrypted Message

Original body of message will be encrypted by AES CBC. The key will be randomly generated for each message. The key is used to encrypt the message body. We need all recipients' public key in ed25519 format to encrypt the message key respectively. After the recipient receive the message, they need to use the private key (in ed25519 format) with the sender's public key decrypt the message key. Then use the message key decrypt the body of message.

For details of an encrypted message:

version || session size || sender public key || encrypted message key for receiver session 1 || encrypted message key for receiver session 2 || nonce || encrypted message data

1. version: 1 byte
2. session size (2 bytes) in LittleEndian format, max 510, ristricted by participants size of conversation (max 256 right now).
3. sender public key is bot's (maybe user's) curve25519 public key
4. encrypted message key for receiver session = session id || AESCBC(message key, shared secret key, iv)
5. shared secret key = ECDH(sender private key, receiver session public key)
6. message key uses to encrypt the message data

A demo of how to encrypt the body of message can be found here:

checksum of the conversation

The checksum used to validate if there is any change in this conversation. If there's a device signed in again, there session_id will change. Checksum is the md5sum of the conversation session_ids in ASC order.

func GenerateUserChecksum(sessions []*Session) string {
if len(sessions) < 1 {
return ""
sort.Slice(sessions, func(i, j int) bool {
return sessions[i].SessionID < sessions[j].SessionID
h := md5.New()
for _, s := range sessions {
io.WriteString(h, s.SessionID)
sum := h.Sum(nil)
return hex.EncodeToString(sum[:])

Endpoint URL

Authentication and options

LimitationNo limitation

Example request

curl -i -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" --data PAYLOAD

Request body data is a message array:

body payload
"conversation_id": "UUID",
"recipient_id": "UUID",
"message_id": "UUID",
"category": "",
"representative_id": "UUID",
"quote_message_id": "UUID",
"checksum": "md5",
"silent": false,
"data_base64": "Base64 encoded data",
"silent": false

It returns an JSON array for success, witch contains all the messages status.

body payload
"data": [
"type": "message",
"message_id": "UUID",
"recipient_id": "UUID",
"state": "SUCCESS or FAILED",
"sessions": [
"session_id": "UUID",
"public_key": "ed25519 public key",